1 2(********************************************************************) 3(* *) 4(* s7c.sd7 Seed7 compiler - Compiles Seed7 to C *) 5(* Copyright (C) 1990 - 1994, 2004 - 2021 Thomas Mertes *) 6(* *) 7(* This program is free software; you can redistribute it and/or *) 8(* modify it under the terms of the GNU General Public License as *) 9(* published by the Free Software Foundation; either version 2 of *) 10(* the License, or (at your option) any later version. *) 11(* *) 12(* This program is distributed in the hope that it will be useful, *) 13(* but WITHOUT ANY WARRANTY; without even the implied warranty of *) 14(* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *) 15(* GNU General Public License for more details. *) 16(* *) 17(* You should have received a copy of the GNU General Public *) 18(* License along with this program; if not, write to the *) 19(* Free Software Foundation, Inc., 51 Franklin Street, *) 20(* Fifth Floor, Boston, MA 02110-1301, USA. *) 21(* *) 22(********************************************************************) 23 24 25$ message "Compiling the compiler ..."; 26$ include "seed7_05.s7i"; 27 include "stdio.s7i"; 28 include "osfiles.s7i"; 29 include "scanstri.s7i"; 30 include "unicode.s7i"; 31 include "bigint.s7i"; 32 include "float.s7i"; 33 include "math.s7i"; 34 include "bytedata.s7i"; 35 include "bin64.s7i"; 36 include "keybd.s7i"; 37 include "progs.s7i"; 38 include "shell.s7i"; 39 include "cc_conf.s7i"; 40 include "inifile.s7i"; 41 include "comp/config.s7i"; 42 include "comp/type.s7i"; 43 include "comp/expr.s7i"; 44 include "comp/debug.s7i"; 45 include "comp/destr.s7i"; 46 include "comp/create.s7i"; 47 include "comp/copy.s7i"; 48 include "comp/expr_utl.s7i"; 49 include "comp/stat.s7i"; 50 include "comp/inline.s7i"; 51 include "comp/const.s7i"; 52 include "comp/literal.s7i"; 53 include "comp/intrange.s7i"; 54 include "comp/error.s7i"; 55 include "comp/library.s7i"; 56 include "comp/action.s7i"; 57 58const string: temp_marker is "/* Seed7 compiler temp file */"; 59 60const boolean: SHOW_STATISTIC is FALSE; 61 62const type: option_hash is hash [string] string; 63 64var option_hash: compiler_option is option_hash.value; 65var boolean: compileLibrary is FALSE; 66 67var array string: libraryDirs is 0 times ""; 68 69var reference: main_object is NIL; 70var file: c_prog is STD_NULL; 71 72var integer: countDeclarations is 0; 73var expr_type: global_init is expr_type.value; 74 75const type: globalInitHash is hash [reference] string; 76 77var globalInitHash: globalInitalisations is globalInitHash.EMPTY_HASH; 78 79const type: interface_hash is hash [type] array type; 80const type: enum_literal_hash is hash [type] element_number_hash; 81const type: act_to_form_param_hash is hash [reference] reference; 82const type: params_added_hash is hash [reference] act_to_form_param_hash; 83const type: setOfCategory is set of category; 84const type: setOfString is set of string; 85const type: funcparam_data_hash is hash [reference] string; 86const type: element_repeat_count_hash is hash [reference] integer; 87const type: stringLengthHash is hash [integer] integer; 88const type: lengthToStriNumHash is hash [integer] array integer; 89const type: profiledFunctionsHash is hash [integer] reference; 90 91var boolean_type_hash: generic_cpy_declared is boolean_type_hash.EMPTY_HASH; 92var boolean_type_hash: generic_create_declared is boolean_type_hash.EMPTY_HASH; 93var boolean_type_hash: generic_destr_declared is boolean_type_hash.EMPTY_HASH; 94var boolean_type_hash: generic_cmp_declared is boolean_type_hash.EMPTY_HASH; 95var boolean_obj_hash: return_ref_to_value is boolean_obj_hash.EMPTY_HASH; 96var boolean_obj_hash: function_declared is boolean_obj_hash.EMPTY_HASH; 97var boolean_obj_hash: function_var_declared is boolean_obj_hash.EMPTY_HASH; 98var ref_list: dynamic_functions is ref_list.EMPTY; 99var interface_hash: interfaceOfType is interface_hash.EMPTY_HASH; 100var enum_literal_hash: enum_literal is enum_literal_hash.EMPTY_HASH; 101var params_added_hash: params_added is params_added_hash.EMPTY_HASH; 102var boolean_obj_hash: definedActualFuncParams is boolean_obj_hash.EMPTY_HASH; 103var funcparam_data_hash: funcparam_data is funcparam_data_hash.EMPTY_HASH; 104var funcparam_data_hash: funcparam_reference is funcparam_data_hash.EMPTY_HASH; 105var element_repeat_count_hash: element_repeat_count is element_repeat_count_hash.EMPTY_HASH; 106var profiledFunctionsHash: profiledFunctions is profiledFunctionsHash.value; 107 108 109const func boolean: isFuncParamData (in reference: currExpr) is 110 return currExpr in funcparam_data; 111 112 113const proc: count_declarations (inout expr_type: c_expr) is func 114 115 begin 116 incr(countDeclarations); 117 c_expr.expr &:= "/* "; 118 c_expr.expr &:= str(countDeclarations); 119 c_expr.expr &:= " */\n"; 120 write(OUT, countDeclarations); 121 write(OUT, "\r"); 122 flush(OUT); 123 end func; 124 125 126const proc: process_generic_cpy_declaration (in type: object_type, 127 inout expr_type: c_expr) is func 128 129 begin 130 if object_type not in generic_cpy_declared then 131 process_cpy_declaration(object_type, c_expr); 132 c_expr.expr &:= "static void generic_cpy_"; 133 c_expr.expr &:= str(typeNumber(object_type)); 134 c_expr.expr &:= " (genericType *a, const genericType b)\n"; 135 c_expr.expr &:= "{\n"; 136 process_cpy_call(object_type, 137 "((const_rtlObjectType *) a)->value." & raw_type_value(object_type), 138 "((const_rtlObjectType *) &b)->value." & raw_type_value(object_type), 139 c_expr.expr); 140 c_expr.expr &:= ";\n"; 141 c_expr.expr &:= "}\n\n"; 142 generic_cpy_declared @:= [object_type] TRUE; 143 end if; 144 end func; 145 146 147const proc: process_generic_create_declaration (in type: object_type, 148 inout expr_type: c_expr) is func 149 150 begin 151 if object_type not in generic_create_declared then 152 process_create_declaration(object_type, c_expr); 153 c_expr.expr &:= "static genericType generic_create_"; 154 c_expr.expr &:= str(typeNumber(object_type)); 155 c_expr.expr &:= " (const genericType b)\n"; 156 c_expr.expr &:= "{\n"; 157 c_expr.expr &:= "rtlObjectType result;\n"; 158 c_expr.expr &:= "result.value."; 159 c_expr.expr &:= raw_type_value(object_type); 160 c_expr.expr &:= "="; 161 process_create_call(object_type, 162 "((const_rtlObjectType *) &b)->value." & raw_type_value(object_type), 163 c_expr.expr); 164 c_expr.expr &:= ";\n"; 165 c_expr.expr &:= "return result.value.genericValue;\n"; 166 c_expr.expr &:= "}\n\n"; 167 generic_create_declared @:= [object_type] TRUE; 168 end if; 169 end func; 170 171 172const proc: process_generic_destr_declaration (in type: object_type, 173 inout expr_type: c_expr) is func 174 175 begin 176 if object_type not in generic_destr_declared then 177 process_destr_declaration(object_type, c_expr); 178 c_expr.expr &:= "static void generic_destr_"; 179 c_expr.expr &:= str(typeNumber(object_type)); 180 c_expr.expr &:= " (const genericType b)\n"; 181 c_expr.expr &:= "{\n"; 182 process_destr_call(object_type, 183 "((const_rtlObjectType *) &b)->value." & raw_type_value(object_type), 184 c_expr.expr); 185 c_expr.expr &:= "}\n\n"; 186 generic_destr_declared @:= [object_type] TRUE; 187 end if; 188 end func; 189 190 191const proc: process_generic_cmp_declaration (in reference: function, 192 in type: object_type, inout expr_type: c_expr) is func 193 194 begin 195 if object_type not in generic_cmp_declared then 196 process_cpy_declaration(object_type, c_expr); 197 c_expr.expr &:= "static intType generic_cmp_"; 198 c_expr.expr &:= str(typeNumber(object_type)); 199 c_expr.expr &:= " (const genericType a, const genericType b)\n"; 200 c_expr.expr &:= "{\n"; 201 c_expr.expr &:= "return o_"; 202 create_name(function, c_expr.expr); 203 c_expr.expr &:= "(((const_rtlObjectType *) &a)->value."; 204 c_expr.expr &:= raw_type_value(object_type); 205 c_expr.expr &:= ", ((const_rtlObjectType *) &b)->value."; 206 c_expr.expr &:= raw_type_value(object_type); 207 c_expr.expr &:= ");\n"; 208 c_expr.expr &:= "}\n\n"; 209 generic_cmp_declared @:= [object_type] TRUE; 210 end if; 211 end func; 212 213 214const proc: process_big_create_call (in bigInteger: number, inout string: expr) is func 215 216 begin 217 if number = 0_ then 218 incr(countOptimizations); 219 expr &:= "bigZero(); /* 0_ */\n"; 220 else 221 expr &:= "bigCreate("; 222 expr &:= bigIntegerLiteral(number); 223 expr &:= ");\n"; 224 end if; 225 end func; 226 227 228const proc: process_str_create_call (in string: stri, inout string: expr) is func 229 230 local 231 var char: ch is ' '; 232 var integer: index is 2; 233 begin 234 if stri = "" then 235 incr(countOptimizations); 236 expr &:= "strEmpty(); /* \"\" */\n"; 237 elsif length(stri) = 1 then 238 incr(countOptimizations); 239 expr &:= "chrStr("; 240 expr &:= charLiteral(stri[1]); 241 expr &:= "); /* "; 242 expr &:= literal(stri); 243 expr &:= " */\n"; 244 else 245 ch := stri[1]; 246 while index <= length(stri) and ch = stri[index] do 247 incr(index); 248 end while; 249 if index > length(stri) then 250 incr(countOptimizations); 251 if ch = '\0;' then 252 expr &:= "strZero("; 253 else 254 expr &:= "strChMult("; 255 expr &:= charLiteral(ch); 256 expr &:= ", "; 257 end if; 258 expr &:= integerLiteral(length(stri)); 259 expr &:= ");\n"; 260 else 261 expr &:= "strCreate("; 262 expr &:= stringLiteral(stri); 263 expr &:= ");\n"; 264 end if; 265 end if; 266 end func; 267 268 269const proc: getAnyParamToTempAssigns (in expr_type: c_param, inout expr_type: c_expr) is func 270 271 begin 272 if c_param.result_expr <> "" then 273 c_expr.temp_decls &:= c_param.result_decl; 274 c_expr.temp_frees &:= c_param.result_free; 275 c_expr.temp_to_null &:= c_param.result_to_null; 276 c_expr.temp_assigns &:= c_param.result_intro; 277 c_expr.temp_assigns &:= c_param.result_expr; 278 c_expr.temp_assigns &:= c_param.result_finish; 279 else 280 c_expr.temp_assigns &:= c_param.expr; 281 end if; 282 end func; 283 284 285const proc: getAnyParamToTempAssigns (in reference: aParam, inout expr_type: c_expr) is func 286 287 local 288 var category: exprCategory is category.value; 289 var reference: paramValue is NIL; 290 var string: variableName is ""; 291 var expr_type: c_param is expr_type.value; 292 begin 293 prepareAnyParamTemporarys(aParam, c_param, c_expr); 294 if aParam not in funcparam_data and 295 not isFunc(getType(aParam)) and 296 aParam in inlineParam and 297 inlineParam[aParam][1].paramValue <> NIL then 298 paramValue := inlineParam[aParam][1].paramValue; 299 exprCategory := category(paramValue); 300 if not isVar(paramValue) and 301 (exprCategory = INTOBJECT or 302 exprCategory = FLOATOBJECT or 303 exprCategory = CHAROBJECT or 304 exprCategory = STRIOBJECT or 305 exprCategory = BSTRIOBJECT) then 306 incr(c_expr.temp_num); 307 variableName := "tmp_" & str(c_expr.temp_num); 308 c_expr.temp_decls &:= type_name(getType(paramValue)); 309 c_expr.temp_decls &:= " "; 310 c_expr.temp_decls &:= variableName; 311 c_expr.temp_decls &:= ";\n"; 312 c_expr.temp_assigns &:= "("; 313 c_expr.temp_assigns &:= variableName; 314 c_expr.temp_assigns &:= "="; 315 getAnyParamToTempAssigns(c_param, c_expr); 316 c_expr.temp_assigns &:= ", &"; 317 c_expr.temp_assigns &:= variableName; 318 c_expr.temp_assigns &:= ")"; 319 else 320 c_expr.temp_assigns &:= "&("; 321 getAnyParamToTempAssigns(c_param, c_expr); 322 c_expr.temp_assigns &:= ")"; 323 end if; 324 else 325 c_expr.temp_assigns &:= "&("; 326 getAnyParamToTempAssigns(c_param, c_expr); 327 c_expr.temp_assigns &:= ")"; 328 end if; 329 end func; 330 331 332const func string: enum_value (in reference: current_object) is func 333 334 result 335 var string: enumValue is ""; 336 local 337 var type: enum_type is void; 338 var string: object_name is ""; 339 begin 340 enum_type := getType(current_object); 341 if enum_type in typeCategory and typeCategory[enum_type] = BOOLOBJECT then 342 object_name := str(current_object); 343 if object_name = "FALSE" then 344 enumValue := "0/*FALSE*/"; 345 elsif object_name = "TRUE" then 346 enumValue := "1/*TRUE*/"; 347 end if; 348 else 349 enumValue := "/*" & str(current_object) & "*/"; 350 if enum_type in enum_literal and 351 current_object in enum_literal[enum_type] then 352 enumValue &:= str(enum_literal[enum_type][current_object]); 353 else 354 enumValue &:= str(objNumber(current_object)); 355 end if; 356 end if; 357 end func; 358 359 360const proc: reference_value (in reference: current_value, 361 inout expr_type: c_expr) is func 362 363 begin 364 if current_value = NIL then 365 c_expr.expr &:= "NULL"; 366 else 367 c_expr.expr &:= "&("; 368 process_expr(current_value, c_expr); 369 c_expr.expr &:= ")"; 370 end if; 371 end func; 372 373 374const proc: ref_list_value (in ref_list: current_value, 375 inout expr_type: c_expr) is func 376 377 local 378 var reference: element is NIL; 379 var boolean: first_element is TRUE; 380 begin 381 if length(current_value) = 0 then 382 c_expr.expr &:= "NULL"; 383 else 384 c_expr.expr &:= "{"; 385 for element range current_value do 386 if first_element then 387 first_element := FALSE; 388 else 389 c_expr.expr &:= ", "; 390 end if; 391 c_expr.expr &:= "&("; 392 process_expr(element, c_expr); 393 c_expr.expr &:= ")"; 394 end for; 395 c_expr.expr &:= "}"; 396 end if; 397 end func; 398 399 400const func string: getExprValue (in reference: current_expression, attr string) is func 401 result 402 var string: exprValue is ""; 403 local 404 var reference: evaluated_expression is NIL; 405 begin 406 if category(current_expression) = STRIOBJECT then 407 exprValue := getValue(current_expression, string); 408 else 409 evaluated_expression := evaluate(prog, current_expression); 410 if evaluated_expression <> NIL then 411 exprValue := getValue(evaluated_expression, string); 412 end if; 413 end if; 414 end func; 415 416 417const func boolean: isPointerParam (in reference: a_param) is 418 return category(a_param) = REFPARAMOBJECT and 419 (not valueIsAtHeap(a_param) or isVar(a_param)); 420 421 422const func boolean: isCopyParam (in reference: a_param) is 423 return category(a_param) = VALUEPARAMOBJECT and 424 valueIsAtHeap(a_param); 425 426 427const func boolean: isInOutParam (in reference: a_param) is 428 return category(a_param) = REFPARAMOBJECT and isVar(a_param); 429 430 431const func boolean: canTakeAddress (in reference: an_expression) is func 432 433 result 434 var boolean: canTakeAddress is TRUE; 435 local 436 var category: exprCategory is category.value; 437 var string: action_name is ""; 438 begin 439 exprCategory := category(an_expression); 440 if (exprCategory = INTOBJECT or 441 exprCategory = CHAROBJECT or 442 exprCategory = CONSTENUMOBJECT or 443 exprCategory = FLOATOBJECT) and 444 not isVar(an_expression) then 445 canTakeAddress := FALSE; 446 end if; 447 if isFunc(getType(an_expression)) then 448 canTakeAddress := FALSE; 449 end if; 450 if exprCategory = CALLOBJECT then 451 if category(getValue(an_expression, ref_list)[1]) = ACTOBJECT then 452 action_name := str(getValue(getValue(an_expression, ref_list)[1], ACTION)); 453 if action_name = "ARR_IDX" or 454 action_name = "SCT_SELECT" then 455 canTakeAddress := TRUE; 456 end if; 457 end if; 458 end if; 459 end func; 460 461 462const proc: process_constenumobject (in reference: function, in ref_list: params, 463 inout expr_type: c_expr) is func 464 465 begin 466 c_expr.expr &:= "/*constenumobject*/"; 467 noop_params(formalParams(function), params, c_expr); 468 end func; 469 470 471const func boolean: param_list_okay (in ref_list: formal_params) is func 472 473 result 474 var boolean: okay is TRUE; 475 local 476 var reference: obj is NIL; 477 var category: paramCategory is category.value; 478 begin 479 for obj range formal_params do 480 paramCategory := category(obj); 481 if paramCategory <> SYMBOLOBJECT and paramCategory <> TYPEOBJECT then 482 if isFunc(getType(obj)) then 483 okay := FALSE; 484 end if; 485 end if; 486 end for; 487 end func; 488 489 490const func boolean: containsFunctionCall (in reference: function, 491 in reference: current_expression) is func 492 493 result 494 var boolean: containsCall is FALSE; 495 local 496 var category: exprCategory is category.value; 497 var ref_list: params is ref_list.EMPTY; 498 var reference: currentFunction is NIL; 499 var integer: paramNum is 0; 500 begin 501 exprCategory := category(current_expression); 502 if exprCategory = MATCHOBJECT or exprCategory = CALLOBJECT then 503 params := getValue(current_expression, ref_list); 504 currentFunction := params[1]; 505 if currentFunction = function then 506 containsCall := TRUE; 507 else 508 paramNum := 2; 509 while paramNum <= length(params) and not containsCall do 510 containsCall := containsFunctionCall(function, params[paramNum]); 511 incr(paramNum); 512 end while; 513 end if; 514 elsif exprCategory = BLOCKOBJECT then 515 containsCall := current_expression = function; 516 end if; 517 end func; 518 519 520const func boolean: recursiveFunctionCall (in reference: function, 521 in reference: current_expression) is func 522 523 result 524 var boolean: recursiveCall is FALSE; 525 local 526 var reference: obj is NIL; 527 begin 528 recursiveCall := containsFunctionCall(function, current_expression); 529 if not recursiveCall then 530 for obj range localConsts(function) do 531 if not recursiveCall and category(obj) = BLOCKOBJECT then 532 recursiveCall := containsFunctionCall(function, body(obj)); 533 end if; 534 end for; 535 end if; 536 end func; 537 538 539const func boolean: identical_values (in reference: object1, in reference: object2) is func 540 541 result 542 var boolean: isIdentical is FALSE; 543 local 544 var reference: element1 is NIL; 545 var ref_list: element_list2 is ref_list.EMPTY; 546 var integer: index2 is 0; 547 begin 548 case category(object1) of 549 when {INTOBJECT}: 550 isIdentical := getValue(object1, integer) = getValue(object2, integer); 551 when {BIGINTOBJECT}: 552 isIdentical := getValue(object1, bigInteger) = getValue(object2, bigInteger); 553 when {CHAROBJECT}: 554 isIdentical := getValue(object1, char) = getValue(object2, char); 555 when {STRIOBJECT}: 556 isIdentical := getValue(object1, string) = getValue(object2, string); 557 when {BSTRIOBJECT}: 558 isIdentical := getValue(object1, bstring) = getValue(object2, bstring); 559 when {SETOBJECT}: 560 isIdentical := getValue(object1, bitset) = getValue(object2, bitset); 561 when {FLOATOBJECT}: 562 isIdentical := getValue(object1, float) = getValue(object2, float); 563 when {REFOBJECT}: 564 isIdentical := getValue(object1, reference) = getValue(object2, reference); 565 when {FILEOBJECT}: 566 isIdentical := getValue(object1, clib_file) = getValue(object2, clib_file); 567 when {CONSTENUMOBJECT, VARENUMOBJECT}: 568 isIdentical := getValue(object1, reference) = getValue(object2, reference); 569 when {ARRAYOBJECT}: 570 if arrayMinIdx(object1) = arrayMinIdx(object2) and 571 arrayMaxIdx(object1) = arrayMaxIdx(object2) then 572 isIdentical := TRUE; 573 element_list2 := arrayToList(object2); 574 index2 := 1; 575 for element1 range arrayToList(object1) until not isIdentical do 576 isIdentical := identical_values(element1, element_list2[index2]); 577 incr(index2); 578 end for; 579 end if; 580 when {STRUCTOBJECT}: 581 isIdentical := TRUE; 582 element_list2 := structToList(object2); 583 index2 := 1; 584 for element1 range structToList(object1) until not isIdentical do 585 isIdentical := identical_values(element1, element_list2[index2]); 586 incr(index2); 587 end for; 588 end case; 589 end func; 590 591 592const func boolean: canUseArrTimes (in type: objectType, in reference: arrayValue, 593 inout reference: repeatedElement) is func 594 595 result 596 var boolean: canUseArrTimes is FALSE; 597 local 598 var type: elementType is void; 599 var ref_list: array_list is ref_list.EMPTY; 600 var reference: element is NIL; 601 var reference: previous_element is NIL; 602 var integer: repeat_count is 1; 603 begin 604 if objectType in array_element then 605 elementType := array_element[objectType]; 606 if elementType in typeCategory and 607 typeCategory[elementType] in simpleValueType then 608 array_list := arrayToList(arrayValue); 609 for element range array_list do 610 if previous_element <> NIL then 611 if identical_values(previous_element, element) then 612 incr(repeat_count); 613 end if; 614 end if; 615 previous_element := element; 616 end for; 617 if repeat_count = succ(arrayMaxIdx(arrayValue) - arrayMinIdx(arrayValue)) then 618 canUseArrTimes := TRUE; 619 repeatedElement := array_list[1]; 620 end if; 621 end if; 622 end if; 623 end func; 624 625 626const proc: assignArrayValue (in type: objectType, in reference: arrayValue, 627 inout expr_type: c_declaration) is func 628 629 local 630 var integer: arraySize is 0; 631 var reference: repeatedElement is NIL; 632 var string: variableName is ""; 633 var string: param_value is ""; 634 begin 635 arraySize := succ(arrayMaxIdx(arrayValue) - arrayMinIdx(arrayValue)); 636 if evaluate_const_expr >= 2 and 637 arrayMinIdx(arrayValue) > arrayMaxIdx(arrayValue) then 638 if FALSE and inlineFunctions then 639 incr(c_declaration.temp_num); 640 variableName := "new_arr" <& c_declaration.temp_num; 641 c_declaration.temp_decls &:= ";\n"; 642 c_declaration.temp_decls &:= "arrayType "; 643 c_declaration.temp_decls &:= variableName; 644 c_declaration.temp_assigns &:= "("; 645 c_declaration.temp_assigns &:= variableName; 646 c_declaration.temp_assigns &:= " = (arrayType) malloc(sizeof(struct rtlArrayStruct) - sizeof(rtlObjectType)), (unlikely("; 647 c_declaration.temp_assigns &:= variableName; 648 c_declaration.temp_assigns &:= " == NULL) ? "; 649 c_declaration.temp_assigns &:= "intRaiseError(MEMORY_ERROR) "; 650 c_declaration.temp_assigns &:= ": 0), "; 651 c_declaration.temp_assigns &:= variableName; 652 c_declaration.temp_assigns &:= "->min_position = "; 653 c_declaration.temp_assigns &:= integerLiteral(arrayMinIdx(arrayValue)); 654 c_declaration.temp_assigns &:= ", "; 655 c_declaration.temp_assigns &:= variableName; 656 c_declaration.temp_assigns &:= "->max_position = "; 657 c_declaration.temp_assigns &:= integerLiteral(arrayMaxIdx(arrayValue)); 658 c_declaration.temp_assigns &:= ", "; 659 c_declaration.temp_assigns &:= variableName; 660 c_declaration.temp_assigns &:= ");\n"; 661 else 662 c_declaration.temp_assigns &:= "arrMalloc("; 663 c_declaration.temp_assigns &:= integerLiteral(arrayMinIdx(arrayValue)); 664 c_declaration.temp_assigns &:= ", "; 665 c_declaration.temp_assigns &:= integerLiteral(arrayMaxIdx(arrayValue)); 666 c_declaration.temp_assigns &:= ");\n"; 667 end if; 668 elsif evaluate_const_expr >= 2 and 669 canUseArrTimes(objectType, arrayValue, repeatedElement) and 670 category(repeatedElement) = INTOBJECT then 671 if getValue(repeatedElement, integer) = 0 then 672 incr(c_declaration.temp_num); 673 variableName := "new_arr" <& c_declaration.temp_num; 674 c_declaration.temp_decls &:= ";\n"; 675 c_declaration.temp_decls &:= "arrayType "; 676 c_declaration.temp_decls &:= variableName; 677 c_declaration.temp_assigns &:= "("; 678 c_declaration.temp_assigns &:= variableName; 679 if inlineFunctions and 680 arrayMinIdx(arrayValue) >= -100000000 and arrayMinIdx(arrayValue) <= 100000000 and 681 arraySize <= 100000000 then 682 # The indices are okay and the size given to malloc() will not overflow. 683 c_declaration.temp_assigns &:= " = (arrayType) malloc(sizeof(struct rtlArrayStruct) + "; 684 c_declaration.temp_assigns &:= integerLiteral(pred(arraySize)); 685 c_declaration.temp_assigns &:= " * sizeof(rtlObjectType)), (unlikely("; 686 c_declaration.temp_assigns &:= variableName; 687 c_declaration.temp_assigns &:= " == NULL) ? "; 688 c_declaration.temp_assigns &:= "intRaiseError(MEMORY_ERROR) "; 689 c_declaration.temp_assigns &:= ": 0), "; 690 c_declaration.temp_assigns &:= variableName; 691 c_declaration.temp_assigns &:= "->min_position = "; 692 c_declaration.temp_assigns &:= integerLiteral(arrayMinIdx(arrayValue)); 693 c_declaration.temp_assigns &:= ", "; 694 c_declaration.temp_assigns &:= variableName; 695 c_declaration.temp_assigns &:= "->max_position = "; 696 c_declaration.temp_assigns &:= integerLiteral(arrayMaxIdx(arrayValue)); 697 else 698 # Use arrMalloc(), as it has detailed checks for indices and array size. 699 c_declaration.temp_assigns &:= " = arrMalloc("; 700 c_declaration.temp_assigns &:= integerLiteral(arrayMinIdx(arrayValue)); 701 c_declaration.temp_assigns &:= ", "; 702 c_declaration.temp_assigns &:= integerLiteral(arrayMaxIdx(arrayValue)); 703 c_declaration.temp_assigns &:= ")"; 704 end if; 705 c_declaration.temp_assigns &:= ", memset("; 706 c_declaration.temp_assigns &:= variableName; 707 c_declaration.temp_assigns &:= "->arr, 0, "; 708 c_declaration.temp_assigns &:= integerLiteral(arraySize); 709 c_declaration.temp_assigns &:= " * sizeof(rtlObjectType)), "; 710 c_declaration.temp_assigns &:= variableName; 711 c_declaration.temp_assigns &:= ");\n"; 712 else 713 c_declaration.temp_assigns &:= "arrTimes("; 714 c_declaration.temp_assigns &:= integerLiteral(arrayMinIdx(arrayValue)); 715 c_declaration.temp_assigns &:= ", "; 716 c_declaration.temp_assigns &:= integerLiteral(arrayMaxIdx(arrayValue)); 717 c_declaration.temp_assigns &:= ", (genericType)("; 718 c_declaration.temp_assigns &:= integerLiteral(getValue(repeatedElement, integer)); 719 c_declaration.temp_assigns &:= "));\n"; 720 end if; 721 else 722 if arrayValue not in const_table then 723 const_table @:= [arrayValue] length(const_table); 724 end if; 725 process_create_declaration(objectType, global_c_expr); 726 param_value := "arr["; 727 param_value &:= str(const_table[arrayValue]); 728 param_value &:= "]"; 729 process_create_call(objectType, 730 param_value, c_declaration.temp_assigns); 731 c_declaration.temp_assigns &:= ";\n"; 732 end if; 733 end func; 734 735 736const proc: process_local_declaration (in reference: current_object, in var reference: object_value, 737 inout expr_type: c_expr) is func 738 739 local 740 var type: objectType is void; 741 var category: valueCategory is category.value; 742 var expr_type: c_declaration is expr_type.value; 743 var expr_type: c_value is expr_type.value; 744 var string: param_name is ""; 745 var string: param_value is ""; 746 begin 747 c_declaration.temp_num := c_expr.temp_num; 748 valueCategory := category(object_value); 749 objectType := getType(current_object); 750 if objectType = getType(object_value) and objectType not in typeCategory then 751 typeCategory @:= [objectType] valueCategory; 752 end if; 753 declare_type_if_necessary(objectType, global_c_expr); 754 c_declaration.temp_decls &:= diagnosticLine(current_object); 755 c_declaration.temp_decls &:= type_name(objectType); 756 c_declaration.temp_decls &:= " o_"; 757 create_name(current_object, c_declaration.temp_decls); 758 if objectType in typeCategory and typeCategory[objectType] = INTERFACEOBJECT then 759 if valueCategory = INTERFACEOBJECT then 760 object_value := interfaceToStruct(object_value); 761 valueCategory := category(object_value); 762 end if; 763 if isVar(object_value) then 764 c_declaration.temp_assigns &:= diagnosticLine(current_object); 765 c_declaration.temp_assigns &:= "o_"; 766 create_name(current_object, c_declaration.temp_assigns); 767 c_declaration.temp_assigns &:= "=itfCreate(o_"; 768 create_name(object_value, c_declaration.temp_assigns); 769 c_declaration.temp_assigns &:= "/* "; 770 c_declaration.temp_assigns &:= str(valueCategory); 771 c_declaration.temp_assigns &:= " */);\n"; 772 else 773 if object_value not in const_table then 774 const_table @:= [object_value] length(const_table); 775 end if; 776 c_declaration.temp_assigns &:= diagnosticLine(current_object); 777 c_declaration.temp_assigns &:= "o_"; 778 create_name(current_object, c_declaration.temp_assigns); 779 c_declaration.temp_assigns &:= "=("; 780 c_declaration.temp_assigns &:= type_name(objectType); 781 c_declaration.temp_assigns &:= ")(itfCreate(itf["; 782 c_declaration.temp_assigns &:= str(const_table[object_value]); 783 c_declaration.temp_assigns &:= "]));\n"; 784 end if; 785 process_destr_declaration(objectType, global_c_expr); 786 param_name := "o_"; 787 create_name(current_object, param_name); 788 process_destr_call(objectType, param_name, c_declaration.temp_frees); 789 elsif valueCategory = TYPEOBJECT then 790 c_declaration.temp_decls &:= "="; 791 c_declaration.temp_decls &:= typeLiteral(getValue(object_value, type)); 792 elsif valueCategory = INTOBJECT then 793 c_declaration.temp_decls &:= "="; 794 c_declaration.temp_decls &:= str(getValue(object_value, integer)); 795 elsif valueCategory = BIGINTOBJECT then 796 c_declaration.temp_assigns &:= diagnosticLine(current_object); 797 c_declaration.temp_assigns &:= "o_"; 798 create_name(current_object, c_declaration.temp_assigns); 799 c_declaration.temp_assigns &:= "="; 800 process_big_create_call(getValue(object_value, bigInteger), c_declaration.temp_assigns); 801 c_declaration.temp_frees &:= "bigDestr(o_"; 802 create_name(current_object, c_declaration.temp_frees); 803 c_declaration.temp_frees &:= ");\n"; 804 elsif valueCategory = CHAROBJECT then 805 c_declaration.temp_decls &:= "="; 806 c_declaration.temp_decls &:= charLiteral(getValue(object_value, char)); 807 elsif valueCategory = FLOATOBJECT then 808 c_declaration.temp_decls &:= "="; 809 c_declaration.temp_decls &:= floatLiteral(getValue(object_value, float)); 810 elsif valueCategory = STRIOBJECT then 811 c_declaration.temp_assigns &:= diagnosticLine(current_object); 812 c_declaration.temp_assigns &:= "o_"; 813 create_name(current_object, c_declaration.temp_assigns); 814 c_declaration.temp_assigns &:= "="; 815 process_str_create_call(getValue(object_value, string), c_declaration.temp_assigns); 816 c_declaration.temp_frees &:= "strDestr(o_"; 817 create_name(current_object, c_declaration.temp_frees); 818 c_declaration.temp_frees &:= ");\n"; 819 elsif valueCategory = BSTRIOBJECT then 820 c_declaration.temp_assigns &:= diagnosticLine(current_object); 821 c_declaration.temp_assigns &:= "o_"; 822 create_name(current_object, c_declaration.temp_assigns); 823 c_declaration.temp_assigns &:= "=bstCreate("; 824 c_declaration.temp_assigns &:= bstriLiteral(getValue(object_value, bstring)); 825 c_declaration.temp_assigns &:= ");\n"; 826 c_declaration.temp_frees &:= "bstDestr(o_"; 827 create_name(current_object, c_declaration.temp_frees); 828 c_declaration.temp_frees &:= ");\n"; 829 elsif valueCategory = SETOBJECT then 830 c_declaration.temp_assigns &:= diagnosticLine(current_object); 831 c_declaration.temp_assigns &:= "o_"; 832 create_name(current_object, c_declaration.temp_assigns); 833 c_declaration.temp_assigns &:= "=setCreate("; 834 c_declaration.temp_assigns &:= bitsetLiteral(getValue(object_value, bitset)); 835 c_declaration.temp_assigns &:= ");\n"; 836 c_declaration.temp_frees &:= "setDestr(o_"; 837 create_name(current_object, c_declaration.temp_frees); 838 c_declaration.temp_frees &:= ");\n"; 839 elsif valueCategory = REFOBJECT then 840 c_declaration.temp_decls &:= "="; 841 reference_value(getValue(object_value, reference), c_value); 842 c_declaration.temp_decls &:= c_value.expr; 843 elsif valueCategory = REFLISTOBJECT then 844 c_declaration.temp_decls &:= "="; 845 ref_list_value(getValue(object_value, ref_list), c_value); 846 c_declaration.temp_decls &:= c_value.expr; 847 c_declaration.temp_frees &:= "rflDestr(o_"; 848 create_name(current_object, c_declaration.temp_frees); 849 c_declaration.temp_frees &:= ");\n"; 850 elsif valueCategory = FILEOBJECT then 851 c_declaration.temp_decls &:= "=&"; 852 c_declaration.temp_decls &:= lower(literal(getValue(object_value, clib_file))); 853 c_declaration.temp_decls &:= "FileRecord"; 854 c_declaration.temp_frees &:= "filDestr(o_"; 855 create_name(current_object, c_declaration.temp_frees); 856 c_declaration.temp_frees &:= ");\n"; 857 elsif valueCategory = SOCKETOBJECT then 858 c_declaration.temp_decls &:= "=-1"; 859 elsif valueCategory = POLLOBJECT then 860 c_declaration.temp_decls &:= "=NULL"; 861 elsif valueCategory = ARRAYOBJECT then 862 c_declaration.temp_assigns &:= diagnosticLine(current_object); 863 c_declaration.temp_assigns &:= "o_"; 864 create_name(current_object, c_declaration.temp_assigns); 865 c_declaration.temp_assigns &:= "="; 866 assignArrayValue(objectType, object_value, c_declaration); 867 process_destr_declaration(objectType, global_c_expr); 868 param_name := "o_"; 869 create_name(current_object, param_name); 870 process_destr_call(objectType, param_name, c_declaration.temp_frees); 871 elsif valueCategory = STRUCTOBJECT then 872 if object_value not in const_table then 873 const_table @:= [object_value] length(const_table); 874 end if; 875 process_create_declaration(objectType, global_c_expr); 876 process_destr_declaration(objectType, global_c_expr); 877 c_declaration.temp_assigns &:= diagnosticLine(current_object); 878 c_declaration.temp_assigns &:= "o_"; 879 create_name(current_object, c_declaration.temp_assigns); 880 c_declaration.temp_assigns &:= "="; 881 param_value := "sct["; 882 param_value &:= str(const_table[object_value]); 883 param_value &:= "]"; 884 process_create_call(objectType, 885 param_value, c_declaration.temp_assigns); 886 c_declaration.temp_assigns &:= ";\n"; 887 param_name := "o_"; 888 create_name(current_object, param_name); 889 process_destr_call(objectType, param_name, c_declaration.temp_frees); 890 elsif valueCategory = HASHOBJECT then 891 if length(hashKeysToList(object_value)) = 0 then 892 process_destr_declaration(objectType, global_c_expr); 893 incr(countOptimizations); 894 c_declaration.temp_assigns &:= diagnosticLine(current_object); 895 c_declaration.temp_assigns &:= "o_"; 896 create_name(current_object, c_declaration.temp_assigns); 897 c_declaration.temp_assigns &:= "=hshEmpty();\n"; 898 else 899 if object_value not in const_table then 900 const_table @:= [object_value] length(const_table); 901 end if; 902 process_create_declaration(objectType, global_c_expr); 903 process_destr_declaration(objectType, global_c_expr); 904 c_declaration.temp_assigns &:= diagnosticLine(current_object); 905 c_declaration.temp_assigns &:= "o_"; 906 create_name(current_object, c_declaration.temp_assigns); 907 c_declaration.temp_assigns &:= "="; 908 param_value := "hsh["; 909 param_value &:= str(const_table[object_value]); 910 param_value &:= "]"; 911 process_create_call(objectType, 912 param_value, c_declaration.temp_assigns); 913 c_declaration.temp_assigns &:= ";\n"; 914 end if; 915 param_name := "o_"; 916 create_name(current_object, param_name); 917 process_destr_call(objectType, param_name, c_declaration.temp_frees); 918 elsif valueCategory = INTERFACEOBJECT then 919 if object_value not in const_table then 920 const_table @:= [object_value] length(const_table); 921 end if; 922 c_declaration.temp_assigns &:= diagnosticLine(current_object); 923 c_declaration.temp_assigns &:= "o_"; 924 create_name(current_object, c_declaration.temp_assigns); 925 c_declaration.temp_assigns &:= "=itf["; 926 c_declaration.temp_assigns &:= str(const_table[object_value]); 927 c_declaration.temp_assigns &:= "];\n"; 928 process_destr_declaration(objectType, global_c_expr); 929 param_name := "o_"; 930 create_name(current_object, param_name); 931 process_destr_call(objectType, param_name, c_declaration.temp_frees); 932 elsif valueCategory = WINOBJECT then 933 c_declaration.temp_assigns &:= diagnosticLine(current_object); 934 c_declaration.temp_assigns &:= "o_"; 935 create_name(current_object, c_declaration.temp_assigns); 936 c_declaration.temp_assigns &:= "=drwCreate("; 937 c_declaration.temp_assigns &:= windowLiteral(getValue(object_value, PRIMITIVE_WINDOW)); 938 c_declaration.temp_assigns &:= ");\n"; 939 c_declaration.temp_frees &:= "drwDestr(o_"; 940 create_name(current_object, c_declaration.temp_frees); 941 c_declaration.temp_frees &:= ");\n"; 942 elsif valueCategory = PROCESSOBJECT then 943 c_declaration.temp_decls &:= "=NULL"; 944 c_declaration.temp_frees &:= "pcsDestr(o_"; 945 create_name(current_object, c_declaration.temp_frees); 946 c_declaration.temp_frees &:= ");\n"; 947 elsif valueCategory = PROGOBJECT then 948 c_declaration.temp_decls &:= "=NULL"; 949 c_declaration.temp_frees &:= "prgDestr(o_"; 950 create_name(current_object, c_declaration.temp_frees); 951 c_declaration.temp_frees &:= ");\n"; 952 elsif valueCategory = DATABASEOBJECT then 953 c_declaration.temp_decls &:= "=NULL"; 954 c_declaration.temp_frees &:= "sqlDestrDb(o_"; 955 create_name(current_object, c_declaration.temp_frees); 956 c_declaration.temp_frees &:= ");\n"; 957 elsif valueCategory = SQLSTMTOBJECT then 958 c_declaration.temp_decls &:= "=NULL"; 959 c_declaration.temp_frees &:= "sqlDestrStmt(o_"; 960 create_name(current_object, c_declaration.temp_frees); 961 c_declaration.temp_frees &:= ");\n"; 962 elsif valueCategory = CONSTENUMOBJECT then 963 c_declaration.temp_decls &:= "="; 964 c_declaration.temp_decls &:= enum_value(getValue(object_value, reference)); 965 elsif valueCategory = VARENUMOBJECT then 966 c_declaration.temp_decls &:= "="; 967 c_declaration.temp_decls &:= enum_value(getValue(object_value, reference)); 968 elsif valueCategory = ENUMLITERALOBJECT then 969 c_declaration.temp_decls &:= "=o_"; 970 create_name(object_value, c_declaration.temp_decls); 971 elsif valueCategory = CALLOBJECT then 972 param_name := "o_"; 973 create_name(current_object, param_name); 974 c_value.temp_num := c_declaration.temp_num; 975 getTemporaryToResultExpr(object_value, c_value); 976 c_declaration.temp_num := c_value.temp_num; 977 c_expr.temp_decls &:= c_value.temp_decls; 978 c_expr.temp_assigns &:= c_value.temp_assigns; 979 c_expr.temp_frees &:= c_value.temp_frees; 980 c_expr.temp_to_null &:= c_value.temp_to_null; 981 c_declaration.temp_assigns &:= diagnosticLine(current_object); 982 c_declaration.temp_assigns &:= param_name; 983 c_declaration.temp_assigns &:= "=("; 984 c_declaration.temp_assigns &:= type_name(objectType); 985 c_declaration.temp_assigns &:= ")("; 986 c_declaration.temp_assigns &:= c_value.result_expr; 987 c_declaration.temp_assigns &:= ");\n"; 988 process_destr_declaration(objectType, global_c_expr); 989 process_destr_call(objectType, param_name, c_declaration.temp_frees); 990 elsif valueCategory = BLOCKOBJECT then 991 create_name(object_value, objNumber(object_value), param_name); 992 c_value.temp_num := c_declaration.temp_num; 993 processFuncValue(param_name, objectType, object_value, c_value); 994 c_declaration.temp_num := c_value.temp_num; 995 c_declaration.temp_decls &:= "="; 996 c_declaration.temp_decls &:= c_value.expr; 997 c_expr.temp_decls &:= c_value.temp_decls; 998 c_expr.temp_assigns &:= c_value.temp_assigns; 999 c_expr.temp_frees &:= c_value.temp_frees; 1000 c_expr.temp_to_null &:= c_value.temp_to_null; 1001 function_declared @:= [object_value] TRUE; 1002 function_var_declared @:= [current_object] TRUE; 1003 elsif valueCategory = ACTOBJECT then 1004 c_declaration.temp_decls &:= "=NULL"; 1005 else 1006 c_declaration.temp_decls &:= "/* "; 1007 c_declaration.temp_decls &:= str(valueCategory); 1008 c_declaration.temp_decls &:= " */"; 1009 end if; 1010 c_declaration.temp_decls &:= ";\n"; 1011 c_expr.temp_num := c_declaration.temp_num; 1012 c_expr.temp_decls &:= c_declaration.temp_decls; 1013 c_expr.temp_assigns &:= c_declaration.temp_assigns; 1014 c_expr.temp_frees &:= c_declaration.temp_frees; 1015 c_expr.temp_to_null &:= c_declaration.temp_to_null; 1016 end func; 1017 1018 1019const proc: process_local_var_declaration (in reference: current_object, 1020 inout expr_type: c_expr) is func 1021 1022 local 1023 var ref_list: objects is ref_list.EMPTY; 1024 var reference: obj is NIL; 1025 begin 1026 objects := localVars(current_object); 1027 for obj range objects do 1028 process_local_declaration(obj, getValue(obj, reference), c_expr); 1029 end for; 1030 end func; 1031 1032 1033const proc: determineDataForActualFuncParam (in reference: current_expression, 1034 inout ref_list: data_list) is func 1035 1036 local 1037 var category: paramCategory is category.value; 1038 var ref_list: params is ref_list.EMPTY; 1039 var reference: aParam is NIL; 1040 begin 1041 paramCategory := category(current_expression); 1042 if paramCategory = MATCHOBJECT or paramCategory = CALLOBJECT then 1043 params := getValue(current_expression, ref_list); 1044 for aParam range params do 1045 determineDataForActualFuncParam(aParam, data_list); 1046 end for; 1047 elsif paramCategory = LOCALVOBJECT or 1048 paramCategory = VALUEPARAMOBJECT or 1049 paramCategory = REFPARAMOBJECT or 1050 paramCategory = RESULTOBJECT then 1051 if current_expression not in data_list then 1052 data_list &:= make_list(current_expression); 1053 end if; 1054 end if; 1055 end func; 1056 1057 1058const func ref_list: determineDataForActualFuncParam (in reference: current_expression) is func 1059 1060 result 1061 var ref_list: data_list is ref_list.EMPTY; 1062 begin 1063 determineDataForActualFuncParam(current_expression, data_list); 1064 end func; 1065 1066 1067const proc: defineFunctype (in string: valueName, in reference: actual_param, 1068 in ref_list: data_list, inout expr_type: c_expr) is func 1069 local 1070 var reference: dataItem is NIL; 1071 var string: data_value is ""; 1072 begin 1073 c_expr.expr &:= "typedef struct {\n"; 1074 c_expr.expr &:= type_name(resultType(getType(actual_param))); 1075 c_expr.expr &:= " (*func) (void *data_"; 1076 c_expr.expr &:= valueName; 1077 c_expr.expr &:= ");\n"; 1078 c_expr.expr &:= "struct {\n"; 1079 for dataItem range data_list do 1080 if not isVar(dataItem) then 1081 c_expr.expr &:= "const "; 1082 if useConstPrefix(dataItem) then 1083 c_expr.expr &:= "const_"; 1084 end if; 1085 end if; 1086 c_expr.expr &:= type_name(getType(dataItem)); 1087 if isFunc(getType(dataItem)) then 1088 c_expr.expr &:= " data_"; 1089 else 1090 c_expr.expr &:= " *data_"; 1091 end if; 1092 create_name(dataItem, c_expr.expr); 1093 c_expr.expr &:= ";\n"; 1094 if isFunc(getType(dataItem)) then 1095 data_value := "((functype_"; 1096 data_value &:= valueName; 1097 data_value &:= " *) data_"; 1098 data_value &:= valueName; 1099 data_value &:= ")->data.data_"; 1100 create_name(dataItem, data_value); 1101 data_value &:= "->func(((functype_"; 1102 data_value &:= valueName; 1103 data_value &:= " *) data_"; 1104 data_value &:= valueName; 1105 data_value &:= ")->data.data_"; 1106 create_name(dataItem, data_value); 1107 data_value &:= ")"; 1108 if getType(dataItem) = proctype then 1109 data_value &:= ";\n"; 1110 end if; 1111 else 1112 data_value := "*((functype_"; 1113 data_value &:= valueName; 1114 data_value &:= " *) data_"; 1115 data_value &:= valueName; 1116 data_value &:= ")->data.data_"; 1117 create_name(dataItem, data_value); 1118 end if; 1119 funcparam_data @:= [dataItem] data_value; 1120 data_value := "((functype_"; 1121 data_value &:= valueName; 1122 data_value &:= " *) data_"; 1123 data_value &:= valueName; 1124 data_value &:= ")->data.data_"; 1125 create_name(dataItem, data_value); 1126 funcparam_reference @:= [dataItem] data_value; 1127 end for; 1128 c_expr.expr &:= "} data;\n"; 1129 c_expr.expr &:= "} functype_"; 1130 c_expr.expr &:= valueName; 1131 c_expr.expr &:= ";\n\n"; 1132 end func; 1133 1134 1135const proc: defineActualFuncParam (in type: resultType, in string: valueName, 1136 in reference: actual_param, in ref_list: data_list, inout expr_type: c_expr) is func 1137 1138 local 1139 var funcparam_data_hash: funcparam_data_backup is funcparam_data_hash.EMPTY_HASH; 1140 var funcparam_data_hash: funcparam_reference_backup is funcparam_data_hash.EMPTY_HASH; 1141 var expr_type: c_func_body is expr_type.value; 1142 begin 1143 funcparam_data_backup := funcparam_data; 1144 funcparam_reference_backup := funcparam_reference; 1145 if data_list <> ref_list.EMPTY then 1146 defineFunctype(valueName, actual_param, data_list, c_expr); 1147 end if; 1148 c_expr.expr &:= "static "; 1149 c_expr.expr &:= type_name(resultType); 1150 c_expr.expr &:= " func_"; 1151 c_expr.expr &:= valueName; 1152 c_expr.expr &:= " (void *data_"; 1153 c_expr.expr &:= valueName; 1154 c_expr.expr &:= ")\n"; 1155 c_expr.expr &:= "{\n"; 1156 c_func_body.demand := REQUIRE_RESULT; 1157 if category(actual_param) = BLOCKOBJECT then 1158 process_call_by_name_expr(body(actual_param), c_func_body); 1159 else 1160 process_call_by_name_expr(actual_param, c_func_body); 1161 end if; 1162 appendWithDiagnostic(c_func_body.temp_decls, c_expr); 1163 appendWithDiagnostic(c_func_body.temp_assigns, c_expr); 1164 if getType(actual_param) = proctype then 1165 c_expr.expr &:= c_func_body.expr; 1166 appendWithDiagnostic(c_func_body.temp_frees, c_expr); 1167 else 1168 if c_func_body.temp_frees <> "" then 1169 c_expr.expr &:= type_name(resultType); 1170 c_expr.expr &:= " result="; 1171 else 1172 c_expr.expr &:= diagnosticLine(actual_param); 1173 c_expr.expr &:= "return "; 1174 end if; 1175 if c_func_body.result_expr <> "" then 1176 c_expr.expr &:= c_func_body.result_expr; 1177 elsif valueIsAtHeap(resultType) then 1178 process_create_declaration(resultType, global_c_expr); 1179 process_create_call(resultType, c_func_body.expr, c_expr.expr); 1180 else 1181 c_expr.expr &:= c_func_body.expr; 1182 end if; 1183 c_expr.expr &:= ";\n"; 1184 if c_func_body.temp_frees <> "" then 1185 appendWithDiagnostic(c_func_body.temp_frees, c_expr); 1186 c_expr.expr &:= "return result;\n"; 1187 end if; 1188 end if; 1189 c_expr.expr &:= "}\n\n"; 1190 funcparam_data := funcparam_data_backup; 1191 funcparam_reference := funcparam_reference_backup; 1192 end func; 1193 1194 1195const proc: defineFuncValue (in string: valueName, in type: genericFuncType, 1196 in ref_list: data_list, inout expr_type: c_expr) is func 1197 1198 local 1199 var reference: dataItem is NIL; 1200 begin 1201 incr(c_expr.temp_num); 1202 if data_list <> ref_list.EMPTY then 1203 c_expr.temp_decls &:= "functype_"; 1204 c_expr.temp_decls &:= valueName; 1205 else 1206 c_expr.temp_decls &:= "struct_"; 1207 c_expr.temp_decls &:= type_name(genericFuncType); 1208 end if; 1209 c_expr.temp_decls &:= " funcvalue_"; 1210 c_expr.temp_decls &:= valueName; 1211 c_expr.temp_decls &:= ";\n\n"; 1212 c_expr.temp_assigns &:= "funcvalue_"; 1213 c_expr.temp_assigns &:= valueName; 1214 c_expr.temp_assigns &:= ".func = func_"; 1215 c_expr.temp_assigns &:= valueName; 1216 c_expr.temp_assigns &:= ";\n"; 1217 for dataItem range data_list do 1218 c_expr.temp_assigns &:= "funcvalue_"; 1219 c_expr.temp_assigns &:= valueName; 1220 c_expr.temp_assigns &:= ".data.data_"; 1221 create_name(dataItem, c_expr.temp_assigns); 1222 c_expr.temp_assigns &:= " = "; 1223 if isFunc(getType(dataItem)) then 1224 c_expr.temp_assigns &:= "o_"; 1225 create_name(dataItem, c_expr.temp_assigns); 1226 else 1227 getAnyParamToTempAssigns(dataItem, c_expr); 1228 end if; 1229 c_expr.temp_assigns &:= ";\n"; 1230 end for; 1231 end func; 1232 1233 1234const proc: callActualFuncParam (in string: valueName, in type: genericFuncType, 1235 in ref_list: data_list, inout expr_type: c_expr) is func 1236 1237 begin 1238 if data_list <> ref_list.EMPTY then 1239 c_expr.expr &:= "("; 1240 c_expr.expr &:= type_name(genericFuncType); 1241 c_expr.expr &:= " *)("; 1242 end if; 1243 c_expr.expr &:= "&funcvalue_"; 1244 c_expr.expr &:= valueName; 1245 if data_list <> ref_list.EMPTY then 1246 c_expr.expr &:= ")"; 1247 end if; 1248 end func; 1249 1250 1251const proc: processFuncValue (in string: valueName, in type: genericFuncType, 1252 in reference: closure, inout expr_type: c_expr) is func 1253 1254 local 1255 var ref_list: data_list is ref_list.EMPTY; 1256 var expr_type: function_c_expr is expr_type.value; 1257 begin 1258 declare_type_if_necessary(genericFuncType, global_c_expr); 1259 data_list := determineDataForActualFuncParam(closure); 1260 if closure not in definedActualFuncParams then 1261 function_c_expr.currentFile := file(closure); 1262 function_c_expr.currentLine := line(closure); 1263 defineActualFuncParam(resultType(genericFuncType), valueName, closure, 1264 data_list, function_c_expr); 1265 global_c_expr.expr &:= function_c_expr.temp_decls; 1266 global_init.expr &:= function_c_expr.temp_assigns; 1267 global_c_expr.expr &:= function_c_expr.expr; 1268 definedActualFuncParams @:= [closure] TRUE; 1269 end if; 1270 defineFuncValue(valueName, genericFuncType, data_list, c_expr); 1271 if data_list <> ref_list.EMPTY then 1272 c_expr.expr &:= "("; 1273 c_expr.expr &:= type_name(genericFuncType); 1274 c_expr.expr &:= ")("; 1275 end if; 1276 c_expr.expr &:= "&funcvalue_"; 1277 c_expr.expr &:= valueName; 1278 if data_list <> ref_list.EMPTY then 1279 c_expr.expr &:= ")"; 1280 end if; 1281 end func; 1282 1283 1284const proc: processFuncParam (in reference: formal_param, 1285 in reference: actual_param, inout expr_type: c_expr) is func 1286 1287 local 1288 var string: valueName is ""; 1289 begin 1290 create_name(formal_param, objNumber(actual_param), valueName); 1291 processFuncValue(valueName, getType(formal_param), actual_param, c_expr); 1292 end func; 1293 1294 1295const proc: call_params (in ref_list: formal_params, 1296 in ref_list: actual_params, inout expr_type: c_expr) is func 1297 1298 local 1299 var integer: number is 0; 1300 var reference: formal_param is NIL; 1301 var reference: actual_param is NIL; 1302 var category: paramCategory is category.value; 1303 var boolean: first_element is TRUE; 1304 var integer: temp_num is 0; 1305 begin 1306# for number range 1 to length(formal_params) do 1307 for number range 1 to length(actual_params) do 1308 formal_param := formal_params[number]; 1309 actual_param := actual_params[number]; 1310 paramCategory := category(formal_param); 1311 if paramCategory <> SYMBOLOBJECT then 1312 if paramCategory = TYPEOBJECT then 1313 c_expr.expr &:= "/* attr t_"; 1314 c_expr.expr &:= str(typeNumber(getValue(formal_param, type))); 1315 c_expr.expr &:= " "; 1316 c_expr.expr &:= str(getValue(formal_param, type)); 1317 c_expr.expr &:= "*/ "; 1318 elsif getType(formal_param) <> voidtype then 1319 if first_element then 1320 first_element := FALSE; 1321 else 1322 c_expr.expr &:= ", "; 1323 end if; 1324 if isPointerParam(formal_param) then 1325 if category(actual_param) = REFPARAMOBJECT then 1326 if actual_param in inlineParam and 1327 inlineParam[actual_param][1].paramNum <> 0 then 1328 c_expr.expr &:= "par_"; 1329 c_expr.expr &:= str(inlineParam[actual_param][1].paramNum); 1330 c_expr.expr &:= "_"; 1331 end if; 1332 if actual_param in funcparam_reference then 1333 c_expr.expr &:= funcparam_reference[actual_param]; 1334 else 1335 c_expr.expr &:= "o_"; 1336 create_name(actual_param, c_expr.expr); 1337 end if; 1338 elsif category(actual_param) = MATCHOBJECT then 1339 if getValue(actual_param, ref_list)[1] in function_var_declared then 1340 c_expr.expr &:= "o_"; 1341 create_name(getValue(actual_param, ref_list)[1], c_expr.expr); 1342 else 1343 processFuncParam(formal_param, actual_param, c_expr); 1344 end if; 1345 elsif category(actual_param) = BLOCKOBJECT then 1346 if actual_param in function_var_declared then 1347 c_expr.expr &:= "o_"; 1348 create_name(actual_param, c_expr.expr); 1349 else 1350 processFuncParam(formal_param, actual_param, c_expr); 1351 end if; 1352 elsif category(actual_param) = LOCALVOBJECT and 1353 actual_param in function_var_declared then 1354 c_expr.expr &:= "o_"; 1355 create_name(actual_param, c_expr.expr); 1356 elsif canTakeAddress(actual_param) then 1357 c_expr.expr &:= "&("; 1358 process_expr(actual_param, c_expr); 1359 c_expr.expr &:= ")"; 1360 else 1361 c_expr.expr &:= "/* "; 1362 c_expr.expr &:= str(category(actual_param)); 1363 c_expr.expr &:= " */"; 1364 incr(c_expr.temp_num); 1365 temp_num := c_expr.temp_num; 1366 c_expr.temp_decls &:= type_name(getExprResultType(actual_param)); 1367 c_expr.temp_decls &:= " tmp_"; 1368 c_expr.temp_decls &:= str(temp_num); 1369 c_expr.temp_decls &:= ";\n"; 1370 c_expr.expr &:= "(tmp_"; 1371 c_expr.expr &:= str(temp_num); 1372 c_expr.expr &:= "=("; 1373 c_expr.expr &:= type_name(getExprResultType(actual_param)); 1374 c_expr.expr &:= ")("; 1375 getAnyParamToExpr(actual_param, c_expr); 1376 c_expr.expr &:= "), &tmp_"; 1377 c_expr.expr &:= str(temp_num); 1378 c_expr.expr &:= ")"; 1379 end if; 1380 else 1381 getAnyParamToExpr(actual_param, c_expr); 1382 end if; 1383 end if; 1384 end if; 1385 end for; 1386 end func; 1387 1388 1389const proc: process_prototype_declaration (in reference: current_object, 1390 inout expr_type: c_expr) is forward; 1391 1392 1393const proc: process_const_func_call (in reference: function, 1394 in ref_list: actual_params, inout expr_type: c_expr) is func 1395 1396 local 1397 var type: function_type is void; 1398 var type: result_type is void; 1399 var ref_list: formal_params is ref_list.EMPTY; 1400 var expr_type: c_params is expr_type.value; 1401 begin 1402 if function not in prototype_declared then 1403 process_prototype_declaration(function, global_c_expr); 1404 prototype_declared @:= [function] TRUE; 1405 end if; 1406 function_type := getType(function); 1407 result_type := resultType(function_type); 1408 formal_params := formalParams(function); 1409 if valueIsAtHeap(result_type) and 1410 not isVarfunc(function_type) and 1411 function not in return_ref_to_value then 1412 prepare_typed_result(result_type, c_expr); 1413 c_expr.result_expr := "o_"; 1414 create_name(function, c_expr.result_expr); 1415 c_expr.result_expr &:= "("; 1416 c_params.temp_num := c_expr.temp_num; 1417 call_params(formal_params, actual_params, c_params); 1418 c_expr.temp_num := c_params.temp_num; 1419 c_expr.temp_decls &:= c_params.temp_decls; 1420 c_expr.temp_assigns &:= c_params.temp_assigns; 1421 c_expr.temp_frees &:= c_params.temp_frees; 1422 c_expr.temp_to_null &:= c_params.temp_to_null; 1423 c_expr.result_expr &:= c_params.expr; 1424 c_expr.result_expr &:= ")"; 1425 elsif result_type = voidtype then 1426 c_params.temp_num := c_expr.temp_num; 1427 call_params(formal_params, actual_params, c_params); 1428 c_expr.temp_num := c_params.temp_num; 1429 if c_params.temp_decls <> "" or c_params.temp_assigns <> "" then 1430 setDiagnosticLine(c_expr); 1431 c_expr.expr &:= "{\n"; 1432 appendWithDiagnostic(c_params.temp_decls, c_expr); 1433 appendWithDiagnostic(c_params.temp_assigns, c_expr); 1434 end if; 1435 setDiagnosticLine(c_expr); 1436 if isVarfunc(function_type) then 1437 c_expr.expr &:= "*o_"; 1438 else 1439 c_expr.expr &:= "o_"; 1440 end if; 1441 create_name(function, c_expr.expr); 1442 c_expr.expr &:= "("; 1443 c_expr.expr &:= c_params.expr; 1444 c_expr.expr &:= ")"; 1445 c_expr.expr &:= ";\n"; 1446 if c_params.temp_decls <> "" or c_params.temp_assigns <> "" then 1447 appendWithDiagnostic(c_params.temp_frees, c_expr); 1448 setDiagnosticLine(c_expr); 1449 c_expr.expr &:= "}\n"; 1450 end if; 1451 else 1452 if isVarfunc(function_type) then 1453 c_expr.expr &:= "*o_"; 1454 else 1455 c_expr.expr &:= "o_"; 1456 end if; 1457 create_name(function, c_expr.expr); 1458 c_expr.expr &:= "("; 1459 call_params(formal_params, actual_params, c_expr); 1460 c_expr.expr &:= ")"; 1461 end if; 1462 end func; 1463 1464 1465const proc: process_func_call (in reference: function, 1466 in ref_list: actual_params, inout expr_type: c_expr) is func 1467 1468 local 1469 var type: result_type is void; 1470 begin 1471 if isVar(function) then 1472 if getType(function) = proctype then 1473 setDiagnosticLine(c_expr); 1474 end if; 1475 result_type := resultType(getType(function)); 1476 if valueIsAtHeap(result_type) then 1477 prepare_typed_result(result_type, c_expr); 1478 c_expr.result_expr &:= "o_"; 1479 create_name(function, c_expr.result_expr); 1480 c_expr.result_expr &:= "->func(o_"; 1481 create_name(function, c_expr.result_expr); 1482 c_expr.result_expr &:= ")"; 1483 else 1484 c_expr.expr &:= "o_"; 1485 create_name(function, c_expr.expr); 1486 c_expr.expr &:= "->func(o_"; 1487 create_name(function, c_expr.expr); 1488 c_expr.expr &:= ")"; 1489 if getType(function) = proctype then 1490 c_expr.expr &:= ";\n"; 1491 end if; 1492 end if; 1493 else 1494 process_const_func_call(function, actual_params, c_expr); 1495 end if; 1496 end func; 1497 1498 1499const proc: process_call (in reference: current_expression, inout expr_type: c_expr) is func 1500 1501 local 1502 var ref_list: params is ref_list.EMPTY; 1503 var reference: function is NIL; 1504 var category: functionCategory is category.value; 1505 var reference: result_object is NIL; 1506 var reference: obj is NIL; 1507 var boolean: first_element is TRUE; 1508 begin 1509 c_expr.currentFile := file(current_expression); 1510 c_expr.currentLine := line(current_expression); 1511 params := getValue(current_expression, ref_list); 1512 function := params[1]; 1513 params := params[2 ..]; 1514 functionCategory := category(function); 1515 # c_expr.expr &:= "/* process_call "; 1516 # c_expr.expr &:= str(current_expression); 1517 # c_expr.expr &:= " "; 1518 # c_expr.expr &:= str(function); 1519 # c_expr.expr &:= " */"; 1520 if functionCategory = ACTOBJECT then 1521 process_action(function, params, c_expr); 1522 elsif functionCategory = BLOCKOBJECT then 1523 result_object := resultVar(function); 1524 if function in function_declared or result_object <> NIL then 1525 process_func_call(function, params, c_expr); 1526 else 1527 process_inline(function, params, c_expr); 1528 end if; 1529 elsif functionCategory = LOCALVOBJECT then 1530 process_func_call(function, params, c_expr); 1531 elsif functionCategory = CONSTENUMOBJECT then 1532 (* process_constenumobject(function, params, c_expr); *) 1533 process_expr(function, c_expr); 1534 elsif functionCategory = REFPARAMOBJECT then 1535 if isFunc(getType(function)) or 1536 isVarfunc(getType(function)) then 1537 if function in inlineParam then 1538 process_inline_param(function, c_expr); 1539 else 1540 if getType(function) = proctype then 1541 setDiagnosticLine(c_expr); 1542 end if; 1543 c_expr.expr &:= "o_"; 1544 create_name(function, c_expr.expr); 1545 c_expr.expr &:= "->func(o_"; 1546 create_name(function, c_expr.expr); 1547 c_expr.expr &:= ")"; 1548 if getType(function) = proctype then 1549 c_expr.expr &:= ";\n"; 1550 end if; 1551 end if; 1552 else 1553 process_expr(function, c_expr); 1554 end if; 1555 elsif functionCategory = VALUEPARAMOBJECT or 1556 functionCategory = INTOBJECT or 1557 functionCategory = BIGINTOBJECT or 1558 functionCategory = FLOATOBJECT or 1559 functionCategory = CHAROBJECT or 1560 functionCategory = STRIOBJECT or 1561 functionCategory = BSTRIOBJECT or 1562 functionCategory = ARRAYOBJECT or 1563 functionCategory = HASHOBJECT or 1564 functionCategory = SETOBJECT or 1565 functionCategory = STRUCTOBJECT or 1566 functionCategory = INTERFACEOBJECT or 1567 functionCategory = WINOBJECT or 1568 functionCategory = PROCESSOBJECT or 1569 functionCategory = PROGOBJECT or 1570 functionCategory = DATABASEOBJECT or 1571 functionCategory = SQLSTMTOBJECT or 1572 functionCategory = ENUMLITERALOBJECT or 1573 functionCategory = TYPEOBJECT then 1574 process_expr(function, c_expr); 1575 elsif functionCategory = REFOBJECT then 1576 c_expr.expr &:= "o_"; 1577 create_name(function, c_expr.expr); 1578 elsif functionCategory = REFLISTOBJECT then 1579 c_expr.expr &:= "o_"; 1580 create_name(function, c_expr.expr); 1581 elsif functionCategory = FORWARDOBJECT then 1582 error(FORWARD_CALLED, current_expression, function); 1583 else 1584 c_expr.expr &:= "/*[ "; 1585 c_expr.expr &:= str(functionCategory); 1586 c_expr.expr &:= " ]*/"; 1587 c_expr.expr &:= "o_"; 1588 create_name(function, c_expr.expr); 1589 c_expr.expr &:= "("; 1590 for obj range params do 1591 if category(obj) <> SYMBOLOBJECT then 1592 if first_element then 1593 first_element := FALSE; 1594 else 1595 c_expr.expr &:= ", "; 1596 end if; 1597 process_expr(obj, c_expr); 1598 end if; 1599 end for; 1600 c_expr.expr &:= ")"; 1601 end if; 1602 end func; 1603 1604 1605const proc: process_match (in reference: current_expression, inout expr_type: c_expr) is func 1606 1607 local 1608 var ref_list: params is ref_list.EMPTY; 1609 var reference: function is NIL; 1610 var category: functionCategory is category.value; 1611 var reference: result_object is NIL; 1612 var reference: obj is NIL; 1613 var boolean: first_element is TRUE; 1614 begin 1615 c_expr.currentFile := file(current_expression); 1616 c_expr.currentLine := line(current_expression); 1617 # c_expr.expr &:= "/* process_match "; 1618 # c_expr.expr &:= str(current_expression); 1619 # c_expr.expr &:= " */"; 1620 params := getValue(current_expression, ref_list); 1621 function := params[1]; 1622 params := params[2 ..]; 1623 functionCategory := category(function); 1624 if functionCategory = ACTOBJECT then 1625 global_c_expr.expr &:= "objRefType "; 1626 global_c_expr.expr &:= lower(str(getValue(function, ACTION))); 1627 global_c_expr.expr &:= " (listType arguments);\n"; 1628 c_expr.expr &:= "&"; 1629 c_expr.expr &:= lower(str(getValue(function, ACTION))); 1630 elsif functionCategory = BLOCKOBJECT then 1631 c_expr.expr &:= "o_"; 1632 create_name(function, c_expr.expr); 1633 else 1634 raise RANGE_ERROR; 1635 c_expr.expr &:= "/*[ "; 1636 c_expr.expr &:= str(functionCategory); 1637 c_expr.expr &:= " ]*/"; 1638 c_expr.expr &:= "o_"; 1639 create_name(function, c_expr.expr); 1640 c_expr.expr &:= "("; 1641 for obj range params do 1642 if category(obj) <> SYMBOLOBJECT then 1643 if first_element then 1644 first_element := FALSE; 1645 else 1646 c_expr.expr &:= ", "; 1647 end if; 1648 process_expr(obj, c_expr); 1649 end if; 1650 end for; 1651 c_expr.expr &:= ")"; 1652 end if; 1653 end func; 1654 1655 1656const proc: optimize_constant_expressions (inout reference: current_expression, 1657 inout expr_type: c_expr) is func 1658 1659 local 1660 var reference: evaluated_expression is NIL; 1661 begin 1662 if evaluate_const_expr = 3 and isConstantExpr(current_expression) then 1663 block 1664 evaluated_expression := evaluate(prog, current_expression); 1665 if evaluated_expression <> NIL and evaluated_expression <> current_expression then 1666 incr(countEvaluations); 1667 c_expr.expr &:= "/* evaluate "; 1668 if category(getValue(current_expression, ref_list)[1]) = ACTOBJECT then 1669 c_expr.expr &:= str(getValue(getValue(current_expression, ref_list)[1], ACTION)); 1670 elsif category(getValue(current_expression, ref_list)[1]) = BLOCKOBJECT then 1671 c_expr.expr &:= "o_"; 1672 create_name2(getValue(current_expression, ref_list)[1], c_expr.expr); 1673 end if; 1674 c_expr.expr &:= " */ "; 1675 current_expression := evaluated_expression; 1676 if category(current_expression) = VARENUMOBJECT then 1677 current_expression := getValue(current_expression, reference); 1678 else 1679 setVar(current_expression, FALSE); 1680 end if; 1681 end if; 1682 exception 1683 catch NUMERIC_ERROR: c_expr.expr &:= "/* NUMERIC_ERROR */ "; # noop; 1684 catch OVERFLOW_ERROR: c_expr.expr &:= "/* OVERFLOW_ERROR */ "; # noop; 1685 catch RANGE_ERROR: c_expr.expr &:= "/* RANGE_ERROR */ "; # noop; 1686 catch INDEX_ERROR: c_expr.expr &:= "/* INDEX_ERROR */ "; # noop; 1687 catch FILE_ERROR: c_expr.expr &:= "/* FILE_ERROR */ "; # noop; 1688 catch DATABASE_ERROR: c_expr.expr &:= "/* DATABASE_ERROR */ "; # noop; 1689 end block; 1690 end if; 1691 end func; 1692 1693 1694const proc: process_expr (in var reference: current_expression, inout expr_type: c_expr) is func 1695 1696 local 1697 var category: exprCategory is category.value; 1698 begin 1699 optimize_constant_expressions(current_expression, c_expr); 1700 exprCategory := category(current_expression); 1701 if exprCategory = MATCHOBJECT then 1702 process_match(current_expression, c_expr); 1703 elsif exprCategory = CALLOBJECT then 1704 process_call(current_expression, c_expr); 1705 elsif exprCategory = BLOCKOBJECT then 1706 c_expr.expr &:= "o_"; 1707 create_name(current_expression, c_expr.expr); 1708 if not isVar(current_expression) then 1709 c_expr.expr &:= "()"; 1710 if resultType(getType(current_expression)) = voidtype then 1711 c_expr.expr &:= ";\n"; 1712 end if; 1713 end if; 1714 elsif exprCategory = ACTOBJECT then 1715 global_c_expr.expr &:= "objRefType "; 1716 global_c_expr.expr &:= lower(str(getValue(current_expression, ACTION))); 1717 global_c_expr.expr &:= " (listType arguments);\n"; 1718 c_expr.expr &:= "&"; 1719 c_expr.expr &:= lower(str(getValue(current_expression, ACTION))); 1720 elsif exprCategory = LOCALVOBJECT then 1721 if current_expression in funcparam_data then 1722 c_expr.expr &:= funcparam_data[current_expression]; 1723 else 1724 c_expr.expr &:= "o_"; 1725 create_name(current_expression, c_expr.expr); 1726 end if; 1727 elsif exprCategory = VALUEPARAMOBJECT then 1728 if current_expression in funcparam_data then 1729 c_expr.expr &:= funcparam_data[current_expression]; 1730 elsif current_expression in inlineParam and 1731 inlineParam[current_expression][1].paramValue <> NIL then 1732 process_expr(inlineParam[current_expression][1].paramValue, c_expr); 1733 else 1734 if current_expression in inlineParam and 1735 inlineParam[current_expression][1].paramNum <> 0 then 1736 c_expr.expr &:= "par_"; 1737 c_expr.expr &:= str(inlineParam[current_expression][1].paramNum); 1738 c_expr.expr &:= "_"; 1739 end if; 1740 c_expr.expr &:= "o_"; 1741 create_name(current_expression, c_expr.expr); 1742 end if; 1743 elsif exprCategory = REFPARAMOBJECT then 1744 if current_expression in funcparam_data then 1745 c_expr.expr &:= funcparam_data[current_expression]; 1746 elsif isFunc(getType(current_expression)) or 1747 isVarfunc(getType(current_expression)) then 1748 if current_expression in inlineParam then 1749 process_inline_param(current_expression, c_expr); 1750 else 1751 if getType(current_expression) = proctype then 1752 setDiagnosticLine(c_expr); 1753 end if; 1754 c_expr.expr &:= "o_"; 1755 create_name(current_expression, c_expr.expr); 1756 c_expr.expr &:= "->func(o_"; 1757 create_name(current_expression, c_expr.expr); 1758 c_expr.expr &:= ")"; 1759 if getType(current_expression) = proctype then 1760 c_expr.expr &:= ";\n"; 1761 end if; 1762 end if; 1763 elsif current_expression in inlineParam and 1764 inlineParam[current_expression][1].paramValue <> NIL then 1765 process_expr(inlineParam[current_expression][1].paramValue, c_expr); 1766 else 1767 if isPointerParam(current_expression) then 1768 c_expr.expr &:= "*"; 1769 end if; 1770 if current_expression in inlineParam and 1771 inlineParam[current_expression][1].paramNum <> 0 then 1772 c_expr.expr &:= "par_"; 1773 c_expr.expr &:= str(inlineParam[current_expression][1].paramNum); 1774 c_expr.expr &:= "_"; 1775 end if; 1776 c_expr.expr &:= "o_"; 1777 create_name(current_expression, c_expr.expr); 1778 end if; 1779 elsif exprCategory = RESULTOBJECT then 1780 if current_expression in funcparam_data then 1781 c_expr.expr &:= funcparam_data[current_expression]; 1782 else 1783 c_expr.expr &:= "o_"; 1784 create_name(current_expression, c_expr.expr); 1785 end if; 1786 elsif exprCategory = TYPEOBJECT then 1787 if isVar(current_expression) then 1788 c_expr.expr &:= "o_"; 1789 create_name(current_expression, c_expr.expr); 1790 else 1791 c_expr.expr &:= typeLiteral(getValue(current_expression, type)); 1792 end if; 1793 elsif exprCategory = INTOBJECT then 1794 if isVar(current_expression) then 1795 c_expr.expr &:= "o_"; 1796 create_name(current_expression, c_expr.expr); 1797 else 1798 c_expr.expr &:= integerLiteral(getValue(current_expression, integer)); 1799 end if; 1800 elsif exprCategory = BIGINTOBJECT then 1801 if isVar(current_expression) then 1802 c_expr.expr &:= "o_"; 1803 create_name(current_expression, c_expr.expr); 1804 else 1805 c_expr.expr &:= bigIntegerLiteral(getValue(current_expression, bigInteger)); 1806 end if; 1807 elsif exprCategory = FLOATOBJECT then 1808 if isVar(current_expression) then 1809 c_expr.expr &:= "o_"; 1810 create_name(current_expression, c_expr.expr); 1811 else 1812 c_expr.expr &:= floatLiteral(getValue(current_expression, float)); 1813 end if; 1814 elsif exprCategory = CHAROBJECT then 1815 if isVar(current_expression) then 1816 c_expr.expr &:= "o_"; 1817 create_name(current_expression, c_expr.expr); 1818 else 1819 c_expr.expr &:= charLiteral(getValue(current_expression, char)); 1820 end if; 1821 elsif exprCategory = STRIOBJECT then 1822 if isVar(current_expression) then 1823 c_expr.expr &:= "o_"; 1824 create_name(current_expression, c_expr.expr); 1825 else 1826 c_expr.expr &:= stringLiteral(getValue(current_expression, string)); 1827 end if; 1828 elsif exprCategory = BSTRIOBJECT then 1829 if isVar(current_expression) then 1830 c_expr.expr &:= "o_"; 1831 create_name(current_expression, c_expr.expr); 1832 else 1833 c_expr.expr &:= bstriLiteral(getValue(current_expression, bstring)); 1834 end if; 1835 elsif exprCategory = SETOBJECT then 1836 if isVar(current_expression) then 1837 c_expr.expr &:= "o_"; 1838 create_name(current_expression, c_expr.expr); 1839 else 1840 c_expr.expr &:= "("; 1841 c_expr.expr &:= type_name(getType(current_expression)); 1842 c_expr.expr &:= ")("; 1843 c_expr.expr &:= bitsetLiteral(getValue(current_expression, bitset)); 1844 c_expr.expr &:= ")"; 1845 end if; 1846 elsif exprCategory = REFOBJECT then 1847 if isVar(current_expression) then 1848 c_expr.expr &:= "o_"; 1849 create_name(current_expression, c_expr.expr); 1850 else 1851 if getValue(current_expression, reference) = NIL then 1852 c_expr.expr &:= "NULL"; 1853 else 1854 c_expr.expr &:= "&("; 1855 process_expr(getValue(current_expression, reference), c_expr); 1856 c_expr.expr &:= ")"; 1857 end if; 1858 end if; 1859 elsif exprCategory = REFLISTOBJECT then 1860 c_expr.expr &:= "o_"; 1861 create_name(current_expression, c_expr.expr); 1862 elsif exprCategory = ARRAYOBJECT then 1863 if isVar(current_expression) then 1864 c_expr.expr &:= "o_"; 1865 create_name(current_expression, c_expr.expr); 1866 else 1867 if current_expression not in const_table then 1868 const_table @:= [current_expression] length(const_table); 1869 end if; 1870 c_expr.expr &:= "arr["; 1871 c_expr.expr &:= str(const_table[current_expression]); 1872 c_expr.expr &:= "]"; 1873 end if; 1874 elsif exprCategory = STRUCTOBJECT then 1875 if isVar(current_expression) then 1876 c_expr.expr &:= "o_"; 1877 create_name(current_expression, c_expr.expr); 1878 else 1879 if current_expression not in const_table then 1880 const_table @:= [current_expression] length(const_table); 1881 end if; 1882 c_expr.expr &:= "sct["; 1883 c_expr.expr &:= str(const_table[current_expression]); 1884 c_expr.expr &:= "]"; 1885 end if; 1886 elsif exprCategory = HASHOBJECT then 1887 if isVar(current_expression) then 1888 c_expr.expr &:= "o_"; 1889 create_name(current_expression, c_expr.expr); 1890 else 1891 if current_expression not in const_table then 1892 const_table @:= [current_expression] length(const_table); 1893 end if; 1894 c_expr.expr &:= "hsh["; 1895 c_expr.expr &:= str(const_table[current_expression]); 1896 c_expr.expr &:= "]"; 1897 end if; 1898 elsif exprCategory = INTERFACEOBJECT then 1899 if isVar(current_expression) then 1900 c_expr.expr &:= "o_"; 1901 create_name(current_expression, c_expr.expr); 1902 else 1903 if current_expression not in const_table then 1904 const_table @:= [current_expression] length(const_table); 1905 end if; 1906 c_expr.expr &:= "itf["; 1907 c_expr.expr &:= str(const_table[current_expression]); 1908 c_expr.expr &:= "]"; 1909 end if; 1910 elsif exprCategory = FILEOBJECT then 1911 c_expr.expr &:= "o_"; 1912 create_name(current_expression, c_expr.expr); 1913 elsif exprCategory = SOCKETOBJECT then 1914 c_expr.expr &:= "o_"; 1915 create_name(current_expression, c_expr.expr); 1916 elsif exprCategory = POLLOBJECT then 1917 c_expr.expr &:= "o_"; 1918 create_name(current_expression, c_expr.expr); 1919 elsif exprCategory = WINOBJECT then 1920 if isVar(current_expression) then 1921 c_expr.expr &:= "o_"; 1922 create_name(current_expression, c_expr.expr); 1923 else 1924 c_expr.expr &:= windowLiteral(getValue(current_expression, PRIMITIVE_WINDOW)); 1925 end if; 1926 elsif exprCategory = PROCESSOBJECT then 1927 if isVar(current_expression) then 1928 c_expr.expr &:= "o_"; 1929 create_name(current_expression, c_expr.expr); 1930 else 1931 if getValue(current_expression, process) = process.EMPTY then 1932 c_expr.expr &:= "/*process.EMPTY*/NULL"; 1933 else 1934 c_expr.expr &:= "o_"; 1935 create_name(current_expression, c_expr.expr); 1936 end if; 1937 end if; 1938 elsif exprCategory = PROGOBJECT then 1939 if isVar(current_expression) then 1940 c_expr.expr &:= "o_"; 1941 create_name(current_expression, c_expr.expr); 1942 else 1943 if getValue(current_expression, program) = program.EMPTY then 1944 c_expr.expr &:= "/*program.EMPTY*/NULL"; 1945 else 1946 c_expr.expr &:= "o_"; 1947 create_name(current_expression, c_expr.expr); 1948 end if; 1949 end if; 1950 elsif exprCategory = DATABASEOBJECT then 1951 if isVar(current_expression) then 1952 c_expr.expr &:= "o_"; 1953 create_name(current_expression, c_expr.expr); 1954 else 1955 c_expr.expr &:= "/*database.value*/NULL"; 1956 end if; 1957 elsif exprCategory = SQLSTMTOBJECT then 1958 if isVar(current_expression) then 1959 c_expr.expr &:= "o_"; 1960 create_name(current_expression, c_expr.expr); 1961 else 1962 c_expr.expr &:= "/*sqlStatement.value*/NULL"; 1963 end if; 1964 elsif exprCategory = CONSTENUMOBJECT then 1965 if isVar(current_expression) then 1966 c_expr.expr &:= "o_"; 1967 create_name(current_expression, c_expr.expr); 1968 else 1969 c_expr.expr &:= enum_value(getValue(current_expression, reference)); 1970 end if; 1971 elsif exprCategory = VARENUMOBJECT then 1972 if current_expression in funcparam_data then 1973 c_expr.expr &:= funcparam_data[current_expression]; 1974 else 1975 c_expr.expr &:= "o_"; 1976 create_name(current_expression, c_expr.expr); 1977 end if; 1978 elsif exprCategory = ENUMLITERALOBJECT then 1979 if getType(current_expression) = voidtype then 1980 c_expr.expr &:= "/* empty */\n"; 1981 else 1982 c_expr.expr &:= "o_"; 1983 create_name(current_expression, c_expr.expr); 1984 end if; 1985 elsif exprCategory = EXPROBJECT then 1986 c_expr.expr &:= "o_"; 1987 create_name(current_expression, c_expr.expr); 1988 elsif exprCategory = SYMBOLOBJECT then 1989 c_expr.expr &:= "/* SYMBOLOBJECT "; 1990 c_expr.expr &:= str(current_expression); 1991 c_expr.expr &:= " */"; 1992 else 1993 c_expr.expr &:= "/* "; 1994 c_expr.expr &:= str(exprCategory); 1995 c_expr.expr &:= " */"; 1996 end if; 1997 end func; 1998 1999 2000const proc: process_call_by_name_expr (in var reference: current_expression, inout expr_type: c_expr) is func 2001 2002 local 2003 var reference: evaluated_expression is NIL; 2004 var category: exprCategory is category.value; 2005 begin 2006 exprCategory := category(current_expression); 2007 if exprCategory = MATCHOBJECT then 2008 process_call(current_expression, c_expr); 2009 elsif exprCategory = LOCALVOBJECT then 2010 if isFunc(getType(current_expression)) or 2011 isVarfunc(getType(current_expression)) then 2012 process_func_call(current_expression, ref_list.EMPTY, c_expr); 2013 else 2014 process_expr(current_expression, c_expr); 2015 end if; 2016 elsif exprCategory = BLOCKOBJECT then 2017 c_expr.expr &:= "o_"; 2018 create_name(current_expression, c_expr.expr); 2019 if not isVar(current_expression) then 2020 c_expr.expr &:= "()"; 2021 if resultType(getType(current_expression)) = voidtype then 2022 c_expr.expr &:= ";\n"; 2023 end if; 2024 end if; 2025 elsif exprCategory = ACTOBJECT then 2026 c_expr.expr &:= "/* process_call_by_name_expr ACTOBJECT "; 2027 c_expr.expr &:= str(getValue(current_expression, ACTION)); 2028 c_expr.expr &:= " */"; 2029 process_action(current_expression, ref_list.EMPTY, c_expr); 2030 else 2031 process_expr(current_expression, c_expr); 2032 end if; 2033 end func; 2034 2035 2036const proc: declare_types_of_params (in ref_list: formal_params, inout expr_type: c_expr) is func 2037 2038 local 2039 var reference: formal_param is NIL; 2040 var category: paramCategory is category.value; 2041 begin 2042 for formal_param range formal_params do 2043 paramCategory := category(formal_param); 2044 if paramCategory <> SYMBOLOBJECT and paramCategory <> TYPEOBJECT then 2045 declare_type_if_necessary(getType(formal_param), c_expr); 2046 end if; 2047 end for; 2048 end func; 2049 2050 2051const proc: process_param_declaration (in reference: formal_param, inout expr_type: c_expr) is func 2052 2053 local 2054 var type: param_type is void; 2055 var string: param_name is ""; 2056 begin 2057 param_type := getType(formal_param); 2058 if isPointerParam(formal_param) then 2059 if isFunc(param_type) or isVarfunc(param_type) then 2060 c_expr.expr &:= type_name(param_type); 2061 c_expr.expr &:= " o_"; 2062 create_name(formal_param, c_expr.expr); 2063 else 2064 if not isVar(formal_param) then 2065 c_expr.expr &:= "const "; 2066 end if; 2067 c_expr.expr &:= type_name(param_type); 2068 c_expr.expr &:= " *const o_"; 2069 create_name(formal_param, c_expr.expr); 2070 end if; 2071 elsif isCopyParam(formal_param) then 2072 create_name(formal_param, param_name); 2073 c_expr.expr &:= "const "; 2074 if useConstPrefix(formal_param) then 2075 c_expr.expr &:= "const_"; 2076 end if; 2077 c_expr.expr &:= type_name(param_type); 2078 c_expr.expr &:= " value_o_"; 2079 c_expr.expr &:= param_name; 2080 if not isVar(formal_param) and useConstPrefix(param_type) then 2081 c_expr.temp_decls &:= "const_"; 2082 end if; 2083 c_expr.temp_decls &:= type_name(param_type); 2084 c_expr.temp_decls &:= " o_"; 2085 c_expr.temp_decls &:= param_name; 2086 c_expr.temp_decls &:= ";\n"; 2087 c_expr.temp_assigns &:= "o_"; 2088 c_expr.temp_assigns &:= param_name; 2089 c_expr.temp_assigns &:= "="; 2090 process_create_declaration(param_type, global_c_expr); 2091 process_create_call(param_type, 2092 "value_o_" & param_name, c_expr.temp_assigns); 2093 c_expr.temp_assigns &:= ";\n"; 2094 process_destr_declaration(param_type, global_c_expr); 2095 process_destr_call(param_type, 2096 "o_" & param_name, c_expr.temp_frees); 2097 else 2098 if not isVar(formal_param) then 2099 c_expr.expr &:= "const "; 2100 if useConstPrefix(formal_param) then 2101 c_expr.expr &:= "const_"; 2102 end if; 2103 end if; 2104 c_expr.expr &:= type_name(param_type); 2105 c_expr.expr &:= " o_"; 2106 create_name(formal_param, c_expr.expr); 2107 end if; 2108 end func; 2109 2110 2111const proc: process_param_list_declaration (in ref_list: formal_params, inout expr_type: c_expr) is func 2112 2113 local 2114 var reference: formal_param is NIL; 2115 var category: paramCategory is category.value; 2116 var boolean: first_element is TRUE; 2117 begin 2118 for formal_param range formal_params do 2119 paramCategory := category(formal_param); 2120 if paramCategory <> SYMBOLOBJECT then 2121 if paramCategory = TYPEOBJECT then 2122 c_expr.expr &:= "/* attr t_"; 2123 c_expr.expr &:= str(typeNumber(getValue(formal_param, type))); 2124 c_expr.expr &:= " "; 2125 c_expr.expr &:= str(getValue(formal_param, type)); 2126 c_expr.expr &:= "*/ "; 2127 elsif getType(formal_param) <> voidtype then 2128 if first_element then 2129 first_element := FALSE; 2130 else 2131 c_expr.expr &:= ", "; 2132 end if; 2133 process_param_declaration(formal_param, c_expr); 2134 end if; 2135 end if; 2136 end for; 2137 if first_element then 2138 c_expr.expr &:= "void"; 2139 end if; 2140 end func; 2141 2142 2143const proc: process_result_declaration (in reference: result_object, 2144 in var reference: result_init, inout expr_type: c_expr) is func 2145 2146 local 2147 var reference: evaluatedExpr is NIL; 2148 begin 2149 if result_object <> NIL then 2150 if evaluate_const_expr >= 2 and isConstant(result_init) then 2151 block 2152 evaluatedExpr := evaluate(prog, result_init); 2153 if evaluatedExpr <> NIL then 2154 incr(countEvaluations); 2155 result_init := evaluatedExpr; 2156 end if; 2157 exception 2158 catch NUMERIC_ERROR: noop; 2159 catch OVERFLOW_ERROR: noop; 2160 catch RANGE_ERROR: noop; 2161 catch INDEX_ERROR: noop; 2162 catch FILE_ERROR: noop; 2163 catch DATABASE_ERROR: noop; 2164 end block; 2165 end if; 2166 process_local_declaration(result_object, result_init, c_expr); 2167 end if; 2168 end func; 2169 2170 2171const proc: process_return (in reference: result_object, 2172 inout expr_type: c_expr) is func 2173 2174 begin 2175 if result_object <> NIL then 2176 c_expr.expr &:= "return o_"; 2177 create_name(result_object, c_expr.expr); 2178 c_expr.expr &:= ";\n"; 2179 end if; 2180 end func; 2181 2182 2183const proc: process_return_value (in reference: function, 2184 in type: result_type, in expr_type: c_func_body, 2185 inout expr_type: c_expr) is func 2186 2187 begin 2188 if isVarfunc(getType(function)) then 2189 c_expr.expr &:= "&("; 2190 if c_func_body.result_expr <> "" then 2191 c_expr.expr &:= c_func_body.result_expr; 2192 else 2193 c_expr.expr &:= c_func_body.expr; 2194 end if; 2195 else 2196 c_expr.expr &:= "("; 2197 if c_func_body.result_expr <> "" then 2198 c_expr.expr &:= c_func_body.result_expr; 2199 else 2200 if function in prototype_declared then 2201 process_create_declaration(result_type, global_c_expr); 2202 process_create_call(result_type, c_func_body.expr, c_expr.expr); 2203 else 2204 if valueIsAtHeap(result_type) then 2205 return_ref_to_value @:= [function] TRUE; 2206 c_expr.expr &:= "/*ref_to_value*/ "; 2207 end if; 2208 c_expr.expr &:= c_func_body.expr; 2209 end if; 2210 end if; 2211 end if; 2212 c_expr.expr &:= ")"; 2213 end func; 2214 2215 2216const proc: process_local_consts (in reference: function, 2217 inout expr_type: c_expr) is forward; 2218 2219 2220const proc: process_const_func_declaration (in reference: function, 2221 inout expr_type: c_expr) is func 2222 2223 local 2224 var expr_type: c_local_consts is expr_type.value; 2225 var expr_type: c_param_list is expr_type.value; 2226 var expr_type: c_result is expr_type.value; 2227 var expr_type: c_local_vars is expr_type.value; 2228 var expr_type: c_func_body is expr_type.value; 2229 var type: function_type is void; 2230 var type: result_type is void; 2231 var ref_list: param_list is ref_list.EMPTY; 2232 var reference: result_object is NIL; 2233 var reference: result_init is NIL; 2234 begin 2235 function_type := getType(function); 2236 result_type := resultType(function_type); 2237 param_list := formalParams(function); 2238 result_object := resultVar(function); 2239 if param_list_okay(param_list) or 2240 recursiveFunctionCall(function, body(function)) or 2241 result_object <> NIL then 2242 # Try to process the function declaration always. 2243 # The variable write_object_declaration is used to 2244 # decide if the function declaration should be written 2245 function_declared @:= [function] TRUE; 2246 declare_types_of_params(param_list, global_c_expr); 2247 c_local_consts.currentFile := c_expr.currentFile; 2248 c_local_consts.currentLine := c_expr.currentLine; 2249 process_local_consts(function, c_local_consts); 2250 global_c_expr.expr &:= c_local_consts.temp_decls; 2251 global_init.expr &:= c_local_consts.temp_assigns; 2252 global_c_expr.expr &:= c_local_consts.expr; 2253 c_expr.expr &:= diagnosticLine(function); 2254 c_expr.expr &:= "static "; 2255 c_expr.expr &:= type_name(result_type); 2256 if isVarfunc(getType(function)) then 2257 c_expr.expr &:= " /*varfunc*/ *o_"; 2258 else 2259 c_expr.expr &:= " o_"; 2260 end if; 2261 create_name(function, c_expr.expr); 2262 c_expr.expr &:= " ("; 2263 process_param_list_declaration(param_list, c_param_list); 2264 c_expr.expr &:= c_param_list.expr; 2265 c_expr.expr &:= ")\n"; 2266 c_expr.expr &:= "{\n"; 2267 if function_type <> proctype and result_object = NIL then 2268 if isFunctionCallingSpecialAction(function) then 2269 write_object_declaration := FALSE; 2270 end if; 2271 c_func_body.demand := REQUIRE_RESULT; 2272 currentProfiledFunction := function; 2273 process_expr(body(function), c_func_body); 2274 if c_param_list.temp_decls <> "" or c_func_body.temp_decls <> "" or 2275 trace_function or profile_function then 2276 c_expr.currentFile := file(body(function)); 2277 c_expr.currentLine := line(body(function)); 2278 setDiagnosticLine(c_expr); 2279 c_expr.expr &:= type_name(result_type); 2280 if isVarfunc(getType(function)) then 2281 c_expr.expr &:= " *result;\n"; 2282 else 2283 c_expr.expr &:= " result;\n"; 2284 end if; 2285 appendWithDiagnostic(c_param_list.temp_decls, c_expr); 2286 appendWithDiagnostic(c_func_body.temp_decls, c_expr); 2287 if trace_function then 2288 c_expr.expr &:= "printf(\"-> "; 2289 create_name(function, c_expr.expr); 2290 c_expr.expr &:= "\\n\");\n"; 2291 c_expr.expr &:= "fflush(stdout);\n"; 2292 end if; 2293 if profile_function then 2294 profiledFunctions @:= [objNumber(function)] function; 2295 c_expr.expr &:= "profile["; 2296 c_expr.expr &:= str(objNumber(function)); 2297 c_expr.expr &:= "].count++;\n"; 2298 c_expr.expr &:= "if (profile["; 2299 c_expr.expr &:= str(objNumber(function)); 2300 c_expr.expr &:= "].depth == 0) {\n"; 2301 c_expr.expr &:= " profile["; 2302 c_expr.expr &:= str(objNumber(function)); 2303 c_expr.expr &:= "].time -= timMicroSec();\n"; 2304 c_expr.expr &:= "}\n"; 2305 c_expr.expr &:= "profile["; 2306 c_expr.expr &:= str(objNumber(function)); 2307 c_expr.expr &:= "].depth++;\n"; 2308 end if; 2309 appendWithDiagnostic(c_param_list.temp_assigns, c_expr); 2310 appendWithDiagnostic(c_func_body.temp_assigns, c_expr); 2311 setDiagnosticLine(c_expr); 2312 c_expr.expr &:= "result=("; 2313 c_expr.expr &:= type_name(result_type); 2314 if isVarfunc(getType(function)) then 2315 c_expr.expr &:= " *"; 2316 end if; 2317 c_expr.expr &:= ")("; 2318 process_return_value(function, result_type, c_func_body, c_expr); 2319 c_expr.expr &:= ");\n"; 2320 appendWithDiagnostic(c_param_list.temp_frees, c_expr); 2321 appendWithDiagnostic(c_func_body.temp_frees, c_expr); 2322 if profile_function then 2323 c_expr.expr &:= "profile["; 2324 c_expr.expr &:= str(objNumber(function)); 2325 c_expr.expr &:= "].depth--;\n"; 2326 c_expr.expr &:= "if (profile["; 2327 c_expr.expr &:= str(objNumber(function)); 2328 c_expr.expr &:= "].depth == 0) {\n"; 2329 c_expr.expr &:= " profile["; 2330 c_expr.expr &:= str(objNumber(function)); 2331 c_expr.expr &:= "].time += timMicroSec();\n"; 2332 c_expr.expr &:= "}\n"; 2333 end if; 2334 if trace_function then 2335 c_expr.expr &:= "printf(\"<- "; 2336 create_name(function, c_expr.expr); 2337 c_expr.expr &:= "\\n\");\n"; 2338 c_expr.expr &:= "fflush(stdout);\n"; 2339 end if; 2340 setDiagnosticLine(c_expr); 2341 c_expr.expr &:= "return result;\n"; 2342 else 2343 c_expr.expr &:= diagnosticLine(body(function)); 2344 c_expr.expr &:= "return ("; 2345 c_expr.expr &:= type_name(result_type); 2346 if isVarfunc(getType(function)) then 2347 c_expr.expr &:= " *"; 2348 end if; 2349 c_expr.expr &:= ")("; 2350 process_return_value(function, result_type, c_func_body, c_expr); 2351 c_expr.expr &:= ");\n"; 2352 end if; 2353 else 2354 result_init := resultInitValue(function); 2355 c_result.temp_num := c_expr.temp_num; 2356 process_result_declaration(result_object, result_init, c_result); 2357 c_local_vars.temp_num := c_result.temp_num; 2358 process_local_var_declaration(function, c_local_vars); 2359 c_expr.temp_num := c_local_vars.temp_num; 2360 currentProfiledFunction := function; 2361 process_expr(body(function), c_func_body); 2362 c_expr.currentFile := file(function); 2363 c_expr.currentLine := line(function); 2364 appendWithDiagnostic(c_param_list.temp_decls, c_expr); 2365 c_expr.expr &:= c_result.temp_decls; 2366 c_expr.expr &:= c_local_vars.temp_decls; 2367 appendWithDiagnostic(c_func_body.temp_decls, c_expr); 2368 if trace_function then 2369 c_expr.expr &:= "printf(\"-> "; 2370 create_name(function, c_expr.expr); 2371 c_expr.expr &:= "\\n\");\n"; 2372 c_expr.expr &:= "fflush(stdout);\n"; 2373 end if; 2374 if profile_function then 2375 profiledFunctions @:= [objNumber(function)] function; 2376 c_expr.expr &:= "profile["; 2377 c_expr.expr &:= str(objNumber(function)); 2378 c_expr.expr &:= "].count++;\n"; 2379 c_expr.expr &:= "if (profile["; 2380 c_expr.expr &:= str(objNumber(function)); 2381 c_expr.expr &:= "].depth == 0) {\n"; 2382 c_expr.expr &:= " profile["; 2383 c_expr.expr &:= str(objNumber(function)); 2384 c_expr.expr &:= "].time -= timMicroSec();\n"; 2385 c_expr.expr &:= "}\n"; 2386 c_expr.expr &:= "profile["; 2387 c_expr.expr &:= str(objNumber(function)); 2388 c_expr.expr &:= "].depth++;\n"; 2389 end if; 2390 appendWithDiagnostic(c_param_list.temp_assigns, c_expr); 2391 c_expr.expr &:= c_result.temp_assigns; 2392 c_expr.expr &:= c_local_vars.temp_assigns; 2393 appendWithDiagnostic(c_func_body.temp_assigns, c_expr); 2394 c_expr.expr &:= c_func_body.expr; 2395 appendWithDiagnostic(c_param_list.temp_frees, c_expr); 2396 appendWithDiagnostic(c_local_vars.temp_frees, c_expr); 2397 appendWithDiagnostic(c_func_body.temp_frees, c_expr); 2398 if profile_function then 2399 c_expr.expr &:= "profile["; 2400 c_expr.expr &:= str(objNumber(function)); 2401 c_expr.expr &:= "].depth--;\n"; 2402 c_expr.expr &:= "if (profile["; 2403 c_expr.expr &:= str(objNumber(function)); 2404 c_expr.expr &:= "].depth == 0) {\n"; 2405 c_expr.expr &:= " profile["; 2406 c_expr.expr &:= str(objNumber(function)); 2407 c_expr.expr &:= "].time += timMicroSec();\n"; 2408 c_expr.expr &:= "}\n"; 2409 end if; 2410 if trace_function then 2411 c_expr.expr &:= "printf(\"<- "; 2412 create_name(function, c_expr.expr); 2413 c_expr.expr &:= "\\n\");\n"; 2414 c_expr.expr &:= "fflush(stdout);\n"; 2415 end if; 2416 process_return(result_object, c_expr); 2417 end if; 2418 c_expr.expr &:= "}\n"; 2419 c_expr.expr &:= noDiagnosticLine; 2420 c_expr.expr &:= "\n"; 2421 if write_object_declaration then 2422 prototype_declared @:= [function] TRUE; 2423 count_declarations(c_expr); 2424 else 2425 excl(function_declared, function); 2426 c_expr.expr &:= "/* declare inline o_"; 2427 create_name2(function, c_expr.expr); 2428 c_expr.expr &:= "*/\n\n"; 2429 end if; 2430 else 2431 c_expr.expr &:= "/* declare inline o_"; 2432 create_name2(function, c_expr.expr); 2433 c_expr.expr &:= "*/\n\n"; 2434 end if; 2435 end func; 2436 2437 2438const proc: process_library_initialisation (in reference: current_object, 2439 inout expr_type: c_expr) is func 2440 2441 local 2442 var string: libraryName is ""; 2443 begin 2444 libraryName := name(prog); 2445 c_expr.expr &:= "void init_"; 2446 c_expr.expr &:= libraryName; 2447 c_expr.expr &:= " (void)\n"; 2448 c_expr.expr &:= "{\n"; 2449 c_expr.expr &:= "init_values();\n"; 2450 c_expr.expr &:= "init_globals();\n"; 2451 c_expr.expr &:= "}\n"; 2452 c_expr.expr &:= "\n"; 2453 prototype_declared @:= [current_object] TRUE; 2454 count_declarations(c_expr); 2455 end func; 2456 2457 2458const proc: process_main_declaration (in reference: current_object, 2459 inout expr_type: c_expr) is func 2460 2461 local 2462 var expr_type: c_local_vars is expr_type.value; 2463 var expr_type: c_func_body is expr_type.value; 2464 var string: main_prolog is ""; 2465 var string: main_epilog is ""; 2466 begin 2467 if category(current_object) = BLOCKOBJECT then 2468 function_declared @:= [current_object] TRUE; 2469 process_local_consts(current_object, c_expr); 2470 c_local_vars.temp_num := c_expr.temp_num; 2471 process_local_var_declaration(current_object, c_local_vars); 2472 currentProfiledFunction := main_object; 2473 c_func_body.temp_num := c_local_vars.temp_num; 2474 process_expr(body(current_object), c_func_body); 2475 c_expr.temp_num := c_func_body.temp_num; 2476 elsif category(current_object) = ACTOBJECT then 2477 currentProfiledFunction := main_object; 2478 c_func_body.temp_num := c_local_vars.temp_num; 2479 process_expr(current_object, c_func_body); 2480 c_expr.temp_num := c_func_body.temp_num; 2481 end if; 2482 c_expr.currentFile := file(current_object); 2483 c_expr.currentLine := line(current_object); 2484 if ccConf.USE_WMAIN then 2485 main_prolog := "int wmain (int argc, wchar_t **argv)\n"; 2486 elsif ccConf.USE_WINMAIN then 2487 main_prolog := "int WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, char *lpCmdLine, int nShowCmd)\n"; 2488 else 2489 main_prolog := "int main (int argc, char **argv)\n"; 2490 end if; 2491 main_prolog &:= "\n"; 2492 main_prolog &:= "{\n"; 2493 main_prolog &:= "int fail_value;\n"; 2494 main_prolog &:= "catch_stack_pos = 0;\n"; 2495 main_prolog &:= "max_catch_stack = 128;\n"; 2496 if trace_function then 2497 main_prolog &:= "printf(\"-> main\\n\");\n"; 2498 main_prolog &:= "fflush(stdout);\n"; 2499 end if; 2500 if profile_function then 2501 main_prolog &:= "initProfile();\n"; 2502 profiledFunctions @:= [objNumber(main_object)] main_object; 2503 main_prolog &:= "profile["; 2504 main_prolog &:= str(objNumber(main_object)); 2505 main_prolog &:= "].count++;\n"; 2506 main_prolog &:= "if (profile["; 2507 main_prolog &:= str(objNumber(main_object)); 2508 main_prolog &:= "].depth == 0) {\n"; 2509 main_prolog &:= " profile["; 2510 main_prolog &:= str(objNumber(main_object)); 2511 main_prolog &:= "].time -= timMicroSec();\n"; 2512 main_prolog &:= "}\n"; 2513 main_prolog &:= "profile["; 2514 main_prolog &:= str(objNumber(main_object)); 2515 main_prolog &:= "].depth++;\n"; 2516 end if; 2517 main_prolog &:= "catch_stack = (catch_type *)(malloc(max_catch_stack * sizeof(catch_type)));\n"; 2518 main_prolog &:= "if ((fail_value = do_setjmp(catch_stack[catch_stack_pos])) == 0) {\n"; 2519 main_prolog &:= "setupStack();\n"; 2520 main_prolog &:= "setupRand();\n"; 2521 main_prolog &:= "setupFiles();\n"; 2522 if ccConf.USE_WINMAIN then 2523 main_prolog &:= "arg_v = getArgv(0, NULL, &arg_0, &programName, &programPath);\n"; 2524 else 2525 main_prolog &:= "arg_v = getArgv(argc, argv, &arg_0, &programName, &programPath);\n"; 2526 end if; 2527 main_prolog &:= "setupFloat();\n"; 2528 main_prolog &:= "setupBig();\n"; 2529 main_prolog &:= "init_values();\n"; 2530 main_prolog &:= "setupSignalHandlers(1, " <& ord(trace_signal) <& ", " <& 2531 ord(ccConf.OVERFLOW_SIGNAL <> "") <& 2532 ", 1, NULL);\n"; 2533 main_prolog &:= "init_globals();\n"; 2534 main_prolog &:= "{\n"; 2535 2536 if ccConf.USE_WINMAIN then 2537 c_expr.expr &:= "typedef struct {\n"; 2538 c_expr.expr &:= " int dummy;\n"; 2539 c_expr.expr &:= " } HINSTANCE__;\n"; 2540 c_expr.expr &:= "typedef HINSTANCE__* HINSTANCE;\n"; 2541 c_expr.expr &:= "\n"; 2542 end if; 2543 appendWithDiagnostic(main_prolog, c_expr); 2544 c_expr.expr &:= c_local_vars.temp_decls; 2545 appendWithDiagnostic(c_func_body.temp_decls, c_expr); 2546 c_expr.expr &:= c_local_vars.temp_assigns; 2547 appendWithDiagnostic(c_func_body.temp_assigns, c_expr); 2548 c_expr.expr &:= c_func_body.expr; 2549 appendWithDiagnostic(c_local_vars.temp_frees, c_expr); 2550 appendWithDiagnostic(c_func_body.temp_frees, c_expr); 2551 c_expr.expr &:= "}\n"; 2552 c_expr.expr &:= global_init.temp_frees; 2553 2554 if profile_function then 2555 main_epilog &:= "profile["; 2556 main_epilog &:= str(objNumber(main_object)); 2557 main_epilog &:= "].depth--;\n"; 2558 main_epilog &:= "if (profile["; 2559 main_epilog &:= str(objNumber(main_object)); 2560 main_epilog &:= "].depth == 0) {\n"; 2561 main_epilog &:= " profile["; 2562 main_epilog &:= str(objNumber(main_object)); 2563 main_epilog &:= "].time += timMicroSec();\n"; 2564 main_epilog &:= "}\n"; 2565 main_epilog &:= "{\n"; 2566 main_epilog &:= " FILE *profile_file;\n"; 2567 main_epilog &:= " int index;\n"; 2568 main_epilog &:= " profile_file = fopen(\"profile_out\", \"wb\");\n"; 2569 main_epilog &:= " if (profile_file != NULL) {\n"; 2570 main_epilog &:= " qsort(profile, profile_size, sizeof(struct profileElement),\n"; 2571 main_epilog &:= " cmpProfileElement);\n"; 2572 main_epilog &:= " fprintf(profile_file, \"usecs\\tcalls\\tplace\\tname\\n\");\n"; 2573 main_epilog &:= " for (index = 0; index < profile_size; index++) {\n"; 2574 main_epilog &:= " if (profile[index].count != 0) {\n"; 2575 main_epilog &:= " if (profile[index].depth == 0) {\n"; 2576 main_epilog &:= " fprintf(profile_file, \"%ld\\t%ld\\t%s(%lu)\\t%s\\n\",\n"; 2577 main_epilog &:= " (long) profile[index].time, (long) profile[index].count,\n"; 2578 main_epilog &:= " profile[index].file, (long unsigned) profile[index].line,\n"; 2579 main_epilog &:= " profile[index].name);\n"; 2580 main_epilog &:= " } else {\n"; 2581 main_epilog &:= " fprintf(profile_file, \"*%ld\\t%ld\\t%s(%lu)\\t%s\\n\",\n"; 2582 main_epilog &:= " (long) (profile[index].time + timMicroSec()), (long) profile[index].count,\n"; 2583 main_epilog &:= " profile[index].file, (long unsigned) profile[index].line,\n"; 2584 main_epilog &:= " profile[index].name);\n"; 2585 main_epilog &:= " }\n"; 2586 main_epilog &:= " }\n"; 2587 main_epilog &:= " }\n"; 2588 main_epilog &:= " fclose(profile_file);\n"; 2589 main_epilog &:= " }\n"; 2590 main_epilog &:= "}\n"; 2591 end if; 2592 if trace_function then 2593 main_epilog &:= "printf(\"<- main\\n\");\n"; 2594 main_epilog &:= "fflush(stdout);\n"; 2595 end if; 2596 main_epilog &:= "return 0;\n"; 2597 main_epilog &:= "} else {\n"; 2598 main_epilog &:= " printf(\"\\n*** Uncaught exception \");\n"; 2599 main_epilog &:= " if (fail_value >= 0 && fail_value < sizeof(exception_name) / sizeof(char *)) {\n"; 2600 main_epilog &:= " printf(\"%s\", exception_name[fail_value]);\n"; 2601 main_epilog &:= " } else {\n"; 2602 main_epilog &:= " printf(\"%d\", fail_value);\n"; 2603 main_epilog &:= " }\n"; 2604 main_epilog &:= " printf(\" raised\");\n"; 2605 main_epilog &:= " if (error_file != NULL) {\n"; 2606 main_epilog &:= " printf(\" at %s(%d)\", error_file, error_line);\n"; 2607 main_epilog &:= " }\n"; 2608 main_epilog &:= " printf(\"\\n\");\n"; 2609 if databaseLibraryUsed then 2610 main_epilog &:= " if (fail_value == 6 /*DATABASE_ERROR*/) {\n"; 2611 main_epilog &:= " striType message;\n"; 2612 main_epilog &:= " message = sqlErrMessage();\n"; 2613 main_epilog &:= " printf(\"\\nMessage from the DATABASE_ERROR exception:\\n\");\n"; 2614 if consoleLibraryUsed then 2615 main_epilog &:= " conWrite(message);\n"; 2616 else 2617 main_epilog &:= " ut8Write(&stdoutFileRecord, message);\n"; 2618 end if; 2619 main_epilog &:= " printf(\"\\n\");\n"; 2620 main_epilog &:= " strDestr(message);\n"; 2621 main_epilog &:= " }\n"; 2622 end if; 2623 main_epilog &:= " return 1;\n"; 2624 main_epilog &:= "}\n"; 2625 main_epilog &:= "}\n"; 2626 2627 appendWithDiagnostic(main_epilog, c_expr); 2628 c_expr.expr &:= noDiagnosticLine; 2629 c_expr.expr &:= "\n"; 2630 prototype_declared @:= [current_object] TRUE; 2631 count_declarations(c_expr); 2632 end func; 2633 2634 2635const proc: process_var_func_declaration (in reference: function, 2636 inout expr_type: c_expr) is func 2637 2638 local 2639 var expr_type: c_value is expr_type.value; 2640 var string: valueName is ""; 2641 begin 2642 declare_type_if_necessary(getType(function), global_c_expr); 2643 create_name(function, objNumber(function), valueName); 2644 processFuncValue(valueName, getType(function), function, c_value); 2645 c_expr.expr &:= c_value.temp_decls; 2646 global_init.expr &:= diagnosticLine(function); 2647 global_init.expr &:= c_value.temp_assigns; 2648 c_expr.expr &:= type_name(getType(function)); 2649 c_expr.expr &:= " o_"; 2650 create_name(function, c_expr.expr); 2651 c_expr.expr &:= " = "; 2652 c_expr.expr &:= c_value.expr; 2653 c_expr.expr &:= ";\n\n"; 2654 function_declared @:= [function] TRUE; 2655 function_var_declared @:= [function] TRUE; 2656 end func; 2657 2658 2659const proc: process_func_declaration (in reference: function, 2660 inout expr_type: c_expr) is func 2661 2662 begin 2663 if isVar(function) then 2664 process_var_func_declaration(function, c_expr); 2665 else 2666 process_const_func_declaration(function, c_expr); 2667 end if; 2668 end func; 2669 2670 2671const proc: process_prototype_declaration (in reference: current_object, 2672 inout expr_type: c_expr) is func 2673 2674 local 2675 var expr_type: c_param_list is expr_type.value; 2676 var type: current_type is void; 2677 var type: result_type is void; 2678 var ref_list: param_list is ref_list.EMPTY; 2679 begin 2680 current_type := getType(current_object); 2681 if isFunc(current_type) or isVarfunc(current_type) then 2682 result_type := resultType(current_type); 2683 param_list := formalParams(current_object); 2684 function_declared @:= [current_object] TRUE; 2685 declare_types_of_params(param_list, global_c_expr); 2686 c_expr.expr &:= "static "; 2687 c_expr.expr &:= type_name(result_type); 2688 if isVarfunc(current_type) then 2689 c_expr.expr &:= " *o_"; 2690 else 2691 c_expr.expr &:= " o_"; 2692 end if; 2693 create_name(current_object, c_expr.expr); 2694 c_expr.expr &:= " ("; 2695 process_param_list_declaration(param_list, c_param_list); 2696 c_expr.expr &:= c_param_list.expr; 2697 c_expr.expr &:= ");\n\n"; 2698 else 2699 c_expr.expr &:= "extern "; 2700 c_expr.expr &:= type_name(current_type); 2701 c_expr.expr &:= " o_"; 2702 create_name(current_object, c_expr.expr); 2703 c_expr.expr &:= ";\n\n"; 2704 end if; 2705 end func; 2706 2707 2708const proc: process_forward_declaration (in reference: fwd_ref, 2709 inout expr_type: c_expr) is func 2710 2711 local 2712 var reference: function is NIL; 2713 begin 2714 function := getValue(fwd_ref, reference); 2715 if function not in prototype_declared then 2716 process_prototype_declaration(function, c_expr); 2717 prototype_declared @:= [function] TRUE; 2718 end if; 2719 end func; 2720 2721 2722const proc: process_type_declaration (in reference: current_object, 2723 inout expr_type: c_expr) is func 2724 2725 local 2726 var type: aType is void; 2727 begin 2728 if isVar(current_object) then 2729 c_expr.expr &:= "typeType o_"; 2730 create_name(current_object, c_expr.expr); 2731 c_expr.expr &:= ";\n\n"; 2732 global_init.expr &:= diagnosticLine(current_object); 2733 global_init.expr &:= "o_"; 2734 create_name(current_object, global_init.expr); 2735 global_init.expr &:= "="; 2736 global_init.expr &:= typeLiteral(getValue(current_object, type)); 2737 global_init.expr &:= ";\n"; 2738 else 2739 aType := getValue(current_object, type); 2740 declare_type_if_necessary(aType, c_expr); 2741 end if; 2742 count_declarations(c_expr); 2743 end func; 2744 2745 2746const proc: process_int_declaration (in reference: current_object, 2747 inout expr_type: c_expr) is func 2748 2749 begin 2750 if isVar(current_object) then 2751 c_expr.expr &:= "intType o_"; 2752 create_name(current_object, c_expr.expr); 2753 c_expr.expr &:= "="; 2754 c_expr.expr &:= integerLiteral(getValue(current_object, integer)); 2755 c_expr.expr &:= ";\n\n"; 2756 count_declarations(c_expr); 2757 end if; 2758 end func; 2759 2760 2761const proc: process_bigint_declaration (in reference: current_object, 2762 inout expr_type: c_expr) is func 2763 2764 begin 2765 if isVar(current_object) then 2766 c_expr.expr &:= "bigIntType o_"; 2767 create_name(current_object, c_expr.expr); 2768 c_expr.expr &:= ";\n\n"; 2769 global_init.expr &:= diagnosticLine(current_object); 2770 global_init.expr &:= "o_"; 2771 create_name(current_object, global_init.expr); 2772 global_init.expr &:= "="; 2773 process_big_create_call(getValue(current_object, bigInteger), global_init.expr); 2774 count_declarations(c_expr); 2775 end if; 2776 end func; 2777 2778 2779const proc: process_char_declaration (in reference: current_object, 2780 inout expr_type: c_expr) is func 2781 2782 begin 2783 if isVar(current_object) then 2784 c_expr.expr &:= "charType o_"; 2785 create_name(current_object, c_expr.expr); 2786 c_expr.expr &:= "="; 2787 c_expr.expr &:= charLiteral(getValue(current_object, char)); 2788 c_expr.expr &:= ";\n\n"; 2789 count_declarations(c_expr); 2790 end if; 2791 end func; 2792 2793 2794const proc: process_stri_declaration (in reference: current_object, 2795 inout expr_type: c_expr) is func 2796 2797 begin 2798 if isVar(current_object) then 2799 c_expr.expr &:= "striType o_"; 2800 create_name(current_object, c_expr.expr); 2801 c_expr.expr &:= ";\n\n"; 2802 global_init.expr &:= diagnosticLine(current_object); 2803 global_init.expr &:= "o_"; 2804 create_name(current_object, global_init.expr); 2805 global_init.expr &:= "="; 2806 process_str_create_call(getValue(current_object, string), global_init.expr); 2807 count_declarations(c_expr); 2808 end if; 2809 end func; 2810 2811 2812const proc: process_bstri_declaration (in reference: current_object, 2813 inout expr_type: c_expr) is func 2814 2815 begin 2816 if isVar(current_object) then 2817 c_expr.expr &:= "bstriType o_"; 2818 create_name(current_object, c_expr.expr); 2819 c_expr.expr &:= ";\n\n"; 2820 global_init.expr &:= diagnosticLine(current_object); 2821 global_init.expr &:= "o_"; 2822 create_name(current_object, global_init.expr); 2823 global_init.expr &:= "=bstCreate("; 2824 global_init.expr &:= bstriLiteral(getValue(current_object, bstring)); 2825 global_init.expr &:= ");\n"; 2826 count_declarations(c_expr); 2827 end if; 2828 end func; 2829 2830 2831const proc: process_float_declaration (in reference: current_object, 2832 inout expr_type: c_expr) is func 2833 2834 begin 2835 if isVar(current_object) then 2836 c_expr.expr &:= "floatType o_"; 2837 create_name(current_object, c_expr.expr); 2838 c_expr.expr &:= "="; 2839 c_expr.expr &:= floatLiteral(getValue(current_object, float)); 2840 c_expr.expr &:= ";\n\n"; 2841 count_declarations(c_expr); 2842 end if; 2843 end func; 2844 2845 2846const proc: action_address (in reference: function, inout expr_type: c_expr) is func 2847 2848 local 2849 var ACTION: current_action is action "PRC_NOOP"; 2850 var string: action_name is ""; 2851 var type: object_type is void; 2852 begin 2853 current_action := getValue(function, ACTION); 2854 action_name := str(current_action); 2855 if action_name = "ARR_CPY" then 2856 object_type := getType(formalParams(function)[1]); 2857 process_generic_cpy_declaration(object_type, global_c_expr); 2858 c_expr.expr &:= "&generic_cpy_"; 2859 c_expr.expr &:= str(typeNumber(object_type)); 2860 elsif action_name = "ARR_CREATE" then 2861 object_type := getType(formalParams(function)[1]); 2862 typeCategory @:= [object_type] ARRAYOBJECT; 2863 process_generic_create_declaration(object_type, global_c_expr); 2864 c_expr.expr &:= "&generic_create_"; 2865 c_expr.expr &:= str(typeNumber(object_type)); 2866 elsif action_name = "ARR_DESTR" then 2867 object_type := getType(formalParams(function)[1]); 2868 process_generic_destr_declaration(object_type, global_c_expr); 2869 c_expr.expr &:= "&generic_destr_"; 2870 c_expr.expr &:= str(typeNumber(object_type)); 2871 elsif action_name = "BIG_CMP" then 2872 c_expr.expr &:= "&bigCmpGeneric"; 2873 elsif action_name = "BIG_CPY" then 2874 c_expr.expr &:= "&bigCpyGeneric"; 2875 elsif action_name = "BIG_CREATE" then 2876 c_expr.expr &:= "&bigCreateGeneric"; 2877 elsif action_name = "BIG_DESTR" then 2878 c_expr.expr &:= "&bigDestrGeneric"; 2879 elsif action_name = "BIN_CMP" then 2880 c_expr.expr &:= "&uintCmpGeneric"; 2881 elsif action_name = "BLN_CPY" then 2882 c_expr.expr &:= "&genericCpy"; 2883 elsif action_name = "BLN_CREATE" then 2884 c_expr.expr &:= "&genericCreate"; 2885 elsif action_name = "BST_CMP" then 2886 c_expr.expr &:= "&bstCmpGeneric"; 2887 elsif action_name = "BST_CPY" then 2888 c_expr.expr &:= "&bstCpyGeneric"; 2889 elsif action_name = "BST_CREATE" then 2890 c_expr.expr &:= "&bstCreateGeneric"; 2891 elsif action_name = "BST_DESTR" then 2892 c_expr.expr &:= "&bstDestrGeneric"; 2893 elsif action_name = "CHR_CMP" then 2894 c_expr.expr &:= "&chrCmpGeneric"; 2895 elsif action_name = "CHR_CPY" then 2896 c_expr.expr &:= "&genericCpy"; 2897 elsif action_name = "CHR_CREATE" then 2898 c_expr.expr &:= "&genericCreate"; 2899 elsif action_name = "DRW_CMP" then 2900 c_expr.expr &:= "&ptrCmpGeneric"; 2901 elsif action_name = "DRW_CPY" then 2902 c_expr.expr &:= "&drwCpyGeneric"; 2903 elsif action_name = "DRW_CREATE" then 2904 c_expr.expr &:= "&drwCreateGeneric"; 2905 elsif action_name = "DRW_DESTR" then 2906 c_expr.expr &:= "&drwDestrGeneric"; 2907 elsif action_name = "ENU_CPY" then 2908 c_expr.expr &:= "&genericCpy"; 2909 elsif action_name = "ENU_CREATE" then 2910 c_expr.expr &:= "&genericCreate"; 2911 elsif action_name = "FIL_CPY" then 2912 c_expr.expr &:= "&filCpyGeneric"; 2913 elsif action_name = "FIL_CREATE" then 2914 c_expr.expr &:= "&filCreateGeneric"; 2915 elsif action_name = "FIL_DESTR" then 2916 c_expr.expr &:= "&filDestrGeneric"; 2917 elsif action_name = "FLT_CMP" then 2918 c_expr.expr &:= "&fltCmpGeneric"; 2919 elsif action_name = "FLT_CPY" then 2920 c_expr.expr &:= "&fltCpyGeneric"; 2921 elsif action_name = "FLT_CREATE" then 2922 c_expr.expr &:= "&genericCreate"; 2923 elsif action_name = "GEN_DESTR" then 2924 c_expr.expr &:= "&genericDestr"; 2925 elsif action_name = "INT_CMP" then 2926 c_expr.expr &:= "&intCmpGeneric"; 2927 elsif action_name = "INT_CPY" then 2928 c_expr.expr &:= "&genericCpy"; 2929 elsif action_name = "INT_CREATE" then 2930 c_expr.expr &:= "&genericCreate"; 2931 elsif action_name = "ITF_CMP" then 2932 c_expr.expr &:= "&ptrCmpGeneric"; 2933 elsif action_name = "ITF_CPY" then 2934 object_type := getType(formalParams(function)[1]); 2935 process_generic_cpy_declaration(object_type, global_c_expr); 2936 c_expr.expr &:= "&generic_cpy_"; 2937 c_expr.expr &:= str(typeNumber(object_type)); 2938 elsif action_name = "ITF_CREATE" then 2939 c_expr.expr &:= "&itfCreateGeneric"; 2940 elsif action_name = "ITF_DESTR" then 2941 object_type := getType(formalParams(function)[1]); 2942 process_generic_destr_declaration(object_type, global_c_expr); 2943 c_expr.expr &:= "&generic_destr_"; 2944 c_expr.expr &:= str(typeNumber(object_type)); 2945 elsif action_name = "PCS_CMP" then 2946 c_expr.expr &:= "&pcsCmpGeneric"; 2947 elsif action_name = "PCS_CPY" then 2948 c_expr.expr &:= "&pcsCpyGeneric"; 2949 elsif action_name = "PCS_CREATE" then 2950 c_expr.expr &:= "&pcsCreateGeneric"; 2951 elsif action_name = "PCS_DESTR" then 2952 c_expr.expr &:= "&pcsDestrGeneric"; 2953 elsif action_name = "PRC_NOOP" then 2954 c_expr.expr &:= "&prcNoop"; 2955 elsif action_name = "REF_CMP" then 2956 c_expr.expr &:= "&ptrCmpGeneric"; 2957 elsif action_name = "REF_CPY" then 2958 c_expr.expr &:= "&ptrCpyGeneric"; 2959 elsif action_name = "REF_CREATE" then 2960 c_expr.expr &:= "&ptrCreateGeneric"; 2961 elsif action_name = "RFL_CMP" then 2962 c_expr.expr &:= "&rflCmpGeneric"; 2963 elsif action_name = "RFL_CPY" then 2964 c_expr.expr &:= "&rflCpyGeneric"; 2965 elsif action_name = "RFL_CREATE" then 2966 c_expr.expr &:= "&rflCreateGeneric"; 2967 elsif action_name = "RFL_DESTR" then 2968 c_expr.expr &:= "&rflDestrGeneric"; 2969 elsif action_name = "SCT_CPY" then 2970 object_type := getType(formalParams(function)[1]); 2971 process_generic_cpy_declaration(object_type, global_c_expr); 2972 c_expr.expr &:= "&generic_cpy_"; 2973 c_expr.expr &:= str(typeNumber(object_type)); 2974 elsif action_name = "SCT_CREATE" then 2975 object_type := getType(formalParams(function)[1]); 2976 typeCategory @:= [object_type] STRUCTOBJECT; 2977 process_generic_create_declaration(object_type, global_c_expr); 2978 c_expr.expr &:= "&generic_create_"; 2979 c_expr.expr &:= str(typeNumber(object_type)); 2980 elsif action_name = "SCT_DESTR" then 2981 object_type := getType(formalParams(function)[1]); 2982 process_generic_destr_declaration(object_type, global_c_expr); 2983 c_expr.expr &:= "&generic_destr_"; 2984 c_expr.expr &:= str(typeNumber(object_type)); 2985 elsif action_name = "SET_CMP" then 2986 c_expr.expr &:= "&setCmpGeneric"; 2987 elsif action_name = "SET_CPY" then 2988 c_expr.expr &:= "&setCpyGeneric"; 2989 elsif action_name = "SET_CREATE" then 2990 c_expr.expr &:= "&setCreateGeneric"; 2991 elsif action_name = "SET_DESTR" then 2992 c_expr.expr &:= "&setDestrGeneric"; 2993 elsif action_name = "SQL_CMP_DB" then 2994 c_expr.expr &:= "&ptrCmpGeneric"; 2995 elsif action_name = "SQL_CPY_DB" then 2996 c_expr.expr &:= "&sqlCpyDbGeneric"; 2997 elsif action_name = "SQL_CREATE_DB" then 2998 c_expr.expr &:= "&sqlCreateDbGeneric"; 2999 elsif action_name = "SQL_DESTR_DB" then 3000 c_expr.expr &:= "&sqlDestrDbGeneric"; 3001 elsif action_name = "SQL_CMP_STMT" then 3002 c_expr.expr &:= "&ptrCmpGeneric"; 3003 elsif action_name = "SQL_CPY_STMT" then 3004 c_expr.expr &:= "&sqlCpyStmtGeneric"; 3005 elsif action_name = "SQL_CREATE_STMT" then 3006 c_expr.expr &:= "&sqlCreateStmtGeneric"; 3007 elsif action_name = "SQL_DESTR_STMT" then 3008 c_expr.expr &:= "&sqlDestrStmtGeneric"; 3009 elsif action_name = "STR_CMP" then 3010 c_expr.expr &:= "&strCmpGeneric"; 3011 elsif action_name = "STR_CPY" then 3012 c_expr.expr &:= "&strCpyGeneric"; 3013 elsif action_name = "STR_CREATE" then 3014 c_expr.expr &:= "&strCreateGeneric"; 3015 elsif action_name = "STR_DESTR" then 3016 c_expr.expr &:= "&strDestrGeneric"; 3017 elsif action_name = "TYP_CMP" then 3018 c_expr.expr &:= "&typCmpGeneric"; 3019 elsif action_name = "TYP_CPY" then 3020 c_expr.expr &:= "&ptrCpyGeneric"; 3021 elsif action_name = "TYP_CREATE" then 3022 c_expr.expr &:= "&ptrCreateGeneric"; 3023 elsif action_name = "TYP_DESTR" then 3024 c_expr.expr &:= "&genericDestr"; 3025 else 3026 c_expr.expr &:= "NULL /* ACTOBJECT { "; 3027 c_expr.expr &:= action_name; 3028 c_expr.expr &:= " }*/"; 3029 end if; 3030 end func; 3031 3032 3033const proc: block_address (in reference: function, inout expr_type: c_expr) is func 3034 3035 local 3036 var ref_list: formal_params is ref_list.EMPTY; 3037 var reference: formal_param is NIL; 3038 var type: object_type is void; 3039 var boolean: address_written is FALSE; 3040 begin 3041 formal_params := formalParams(function); 3042 if length(formal_params) = 3 and category(formal_params[2]) = SYMBOLOBJECT and 3043 str(formal_params[2]) = ":=" then 3044 formal_param := formal_params[1]; 3045 object_type := getType(formal_param); 3046 process_generic_cpy_declaration(object_type, global_c_expr); 3047 c_expr.expr &:= "&generic_cpy_"; 3048 c_expr.expr &:= str(typeNumber(object_type)); 3049 address_written := TRUE; 3050 elsif length(formal_params) = 3 and category(formal_params[2]) = SYMBOLOBJECT and 3051 str(formal_params[2]) = "::=" then 3052 formal_param := formal_params[1]; 3053 object_type := getType(formal_param); 3054 process_generic_create_declaration(object_type, global_c_expr); 3055 c_expr.expr &:= "&generic_create_"; 3056 c_expr.expr &:= str(typeNumber(object_type)); 3057 address_written := TRUE; 3058 elsif length(formal_params) = 2 and category(formal_params[2]) = SYMBOLOBJECT and 3059 str(formal_params[2]) = "destroy" then 3060 formal_param := formal_params[1]; 3061 object_type := getType(formal_param); 3062 process_generic_destr_declaration(object_type, global_c_expr); 3063 c_expr.expr &:= "&generic_destr_"; 3064 c_expr.expr &:= str(typeNumber(object_type)); 3065 address_written := TRUE; 3066 elsif length(formal_params) = 3 and category(formal_params[3]) = SYMBOLOBJECT and 3067 str(formal_params[3]) = "compare" then 3068 formal_param := formal_params[1]; 3069 object_type := getType(formal_param); 3070 process_generic_cmp_declaration(function, object_type, global_c_expr); 3071 c_expr.expr &:= "&generic_cmp_"; 3072 c_expr.expr &:= str(typeNumber(object_type)); 3073 address_written := TRUE; 3074 end if; 3075 if not address_written then 3076 c_expr.expr &:= "&o_"; 3077 create_name(function, c_expr.expr); 3078 end if; 3079 end func; 3080 3081 3082const proc: object_address (in reference: curr_expr, inout expr_type: c_expr) is func 3083 3084 local 3085 var category: exprCategory is category.value; 3086 begin 3087 if curr_expr = NIL then 3088 c_expr.expr &:= "NULL"; 3089 else 3090 exprCategory := category(curr_expr); 3091 if exprCategory = ACTOBJECT then 3092 action_address(curr_expr, c_expr); 3093 elsif exprCategory = BLOCKOBJECT then 3094 block_address(curr_expr, c_expr); 3095 else 3096 c_expr.expr &:= "/* "; 3097 c_expr.expr &:= str(exprCategory); 3098 c_expr.expr &:= " */"; 3099 block 3100 c_expr.expr &:= "&("; 3101 process_expr(curr_expr, c_expr); 3102 c_expr.expr &:= ")"; 3103 exception 3104 catch RANGE_ERROR: 3105 c_expr.expr &:= "/*RANGE_ERROR*/"; 3106 writeln("] "); 3107 TRACE(curr_expr); 3108 writeln; 3109 end block; 3110 end if; 3111 end if; 3112 end func; 3113 3114 3115const proc: process_reference_declaration (in reference: current_object, 3116 inout expr_type: c_expr) is func 3117 3118 begin 3119 (* if isVar(current_object) then *) 3120 c_expr.expr &:= "/* "; 3121 c_expr.expr &:= type_name2(getType(current_object)); 3122 c_expr.expr &:= " */ "; 3123 if useFunctype(current_object) then 3124 c_expr.expr &:= "intfunctype o_"; 3125 else 3126 c_expr.expr &:= "objRefType o_"; 3127 end if; 3128 create_name(current_object, c_expr.expr); 3129 c_expr.expr &:= "="; 3130 if useFunctype(current_object) then 3131 c_expr.expr &:= "(intfunctype)("; 3132 else 3133 c_expr.expr &:= "(objRefType)("; 3134 end if; 3135 object_address(getValue(current_object, reference), c_expr); 3136 c_expr.expr &:= ");\n\n"; 3137 function_pointer_declared @:= [current_object] TRUE; 3138 count_declarations(c_expr); 3139 (* end if; *) 3140 end func; 3141 3142 3143const proc: process_ref_list_declaration (in reference: current_object, 3144 inout expr_type: c_expr) is func 3145 3146 local 3147 var ref_list: refListValue is ref_list.EMPTY; 3148 var integer: index is 0; 3149 begin 3150 refListValue := getValue(current_object, ref_list); 3151 for index range length(refListValue) downto 1 do 3152 c_expr.expr &:= "struct listStruct rec_"; 3153 c_expr.expr &:= str(objNumber(current_object)); 3154 c_expr.expr &:= "_"; 3155 c_expr.expr &:= str(index); 3156 c_expr.expr &:= "={"; 3157 if index = length(refListValue) then 3158 c_expr.expr &:= "NULL"; 3159 else 3160 c_expr.expr &:= "&rec_"; 3161 c_expr.expr &:= str(objNumber(current_object)); 3162 c_expr.expr &:= "_"; 3163 c_expr.expr &:= str(succ(index)); 3164 end if; 3165 c_expr.expr &:= ", (objRefType) &("; 3166 process_expr(refListValue[index], c_expr); 3167 c_expr.expr &:= ")};\n"; 3168 end for; 3169 c_expr.expr &:= "\n"; 3170 c_expr.expr &:= type_name(getType(current_object)); 3171 c_expr.expr &:= " o_"; 3172 create_name(current_object, c_expr.expr); 3173 c_expr.expr &:= "="; 3174 if length(refListValue) = 0 then 3175 c_expr.expr &:= "NULL"; 3176 else 3177 c_expr.expr &:= "&rec_"; 3178 c_expr.expr &:= str(objNumber(current_object)); 3179 c_expr.expr &:= "_1"; 3180 end if; 3181 c_expr.expr &:= ";\n\n"; 3182 count_declarations(c_expr); 3183 end func; 3184 3185 3186const proc: process_file_declaration (in reference: current_object, 3187 inout expr_type: c_expr) is func 3188 3189 begin 3190 c_expr.expr &:= "fileType o_"; 3191 create_name(current_object, c_expr.expr); 3192 c_expr.expr &:= "=&"; 3193 c_expr.expr &:= lower(literal(getValue(current_object, clib_file))); 3194 c_expr.expr &:= "FileRecord;\n\n"; 3195 count_declarations(c_expr); 3196 end func; 3197 3198 3199const proc: process_socket_declaration (in reference: current_object, 3200 inout expr_type: c_expr) is func 3201 3202 begin 3203 c_expr.expr &:= "socketType o_"; 3204 create_name(current_object, c_expr.expr); 3205 c_expr.expr &:= " = (socketType) -1;\n\n"; 3206 count_declarations(c_expr); 3207 end func; 3208 3209 3210const proc: process_poll_declaration (in reference: current_object, 3211 inout expr_type: c_expr) is func 3212 3213 begin 3214 c_expr.expr &:= "pollType o_"; 3215 create_name(current_object, c_expr.expr); 3216 c_expr.expr &:= ";\n\n"; 3217 count_declarations(c_expr); 3218 end func; 3219 3220 3221const proc: process_array_declaration (in reference: current_object, 3222 inout expr_type: c_expr) is func 3223 3224 local 3225 var string: param_value is ""; 3226 begin 3227 typeCategory @:= [getType(current_object)] ARRAYOBJECT; 3228 if isVar(current_object) then 3229 c_expr.expr &:= type_name(getType(current_object)); 3230 c_expr.expr &:= " o_"; 3231 create_name(current_object, c_expr.expr); 3232 c_expr.expr &:= ";\n\n"; 3233 if current_object not in const_table then 3234 const_table @:= [current_object] length(const_table); 3235 end if; 3236 global_init.expr &:= diagnosticLine(current_object); 3237 global_init.expr &:= "o_"; 3238 create_name(current_object, global_init.expr); 3239 global_init.expr &:= "="; 3240 param_value := "("; 3241 param_value &:= type_name(getType(current_object)); 3242 param_value &:= ")(arr["; 3243 param_value &:= str(const_table[current_object]); 3244 param_value &:= "])"; 3245 process_create_declaration(getType(current_object), global_c_expr); 3246 process_create_call(getType(current_object), 3247 param_value, global_init.expr); 3248 global_init.expr &:= ";\n"; 3249 count_declarations(c_expr); 3250 end if; 3251 end func; 3252 3253 3254const proc: process_hash_declaration (in reference: current_object, 3255 inout expr_type: c_expr) is func 3256 3257 local 3258 var string: param_value is ""; 3259 begin 3260 typeCategory @:= [getType(current_object)] HASHOBJECT; 3261 c_expr.expr &:= type_name(getType(current_object)); 3262 c_expr.expr &:= " o_"; 3263 create_name(current_object, c_expr.expr); 3264 c_expr.expr &:= ";\n\n"; 3265 if current_object not in const_table then 3266 const_table @:= [current_object] length(const_table); 3267 end if; 3268 global_init.expr &:= diagnosticLine(current_object); 3269 global_init.expr &:= "o_"; 3270 create_name(current_object, global_init.expr); 3271 global_init.expr &:= "="; 3272 param_value := "("; 3273 param_value &:= type_name(getType(current_object)); 3274 param_value &:= ")(hsh["; 3275 param_value &:= str(const_table[current_object]); 3276 param_value &:= "])"; 3277 if isVar(current_object) then 3278 process_create_declaration(getType(current_object), global_c_expr); 3279 process_create_call(getType(current_object), 3280 param_value, global_init.expr); 3281 else 3282 global_init.expr &:= param_value; 3283 end if; 3284 global_init.expr &:= ";\n"; 3285 count_declarations(c_expr); 3286 end func; 3287 3288 3289const proc: process_set_declaration (in reference: current_object, 3290 inout expr_type: c_expr) is func 3291 3292 begin 3293 if isVar(current_object) then 3294 c_expr.expr &:= type_name(getType(current_object)); 3295 c_expr.expr &:= " o_"; 3296 create_name(current_object, c_expr.expr); 3297 c_expr.expr &:= ";\n\n"; 3298 global_init.expr &:= diagnosticLine(current_object); 3299 global_init.expr &:= "o_"; 3300 create_name(current_object, global_init.expr); 3301 global_init.expr &:= "=setCreate("; 3302 global_init.expr &:= bitsetLiteral(getValue(current_object, bitset)); 3303 global_init.expr &:= ");\n"; 3304 count_declarations(c_expr); 3305 end if; 3306 end func; 3307 3308 3309const proc: process_struct_declaration (in reference: current_object, 3310 inout expr_type: c_expr) is func 3311 3312 local 3313 var string: param_value is ""; 3314 var string: init_expr is ""; 3315 begin 3316 declare_type_if_necessary(getType(current_object), c_expr); 3317 c_expr.expr &:= type_name(getType(current_object)); 3318 c_expr.expr &:= " o_"; 3319 create_name(current_object, c_expr.expr); 3320 c_expr.expr &:= ";\n\n"; 3321 if current_object not in const_table then 3322 const_table @:= [current_object] length(const_table); 3323 end if; 3324 init_expr &:= diagnosticLine(current_object); 3325 init_expr &:= "o_"; 3326 create_name(current_object, init_expr); 3327 init_expr &:= "="; 3328 param_value := "("; 3329 param_value &:= type_name(getType(current_object)); 3330 param_value &:= ")(sct["; 3331 param_value &:= str(const_table[current_object]); 3332 param_value &:= "])"; 3333 if isVar(current_object) then 3334 process_create_declaration(getType(current_object), global_c_expr); 3335 process_create_call(getType(current_object), 3336 param_value, init_expr); 3337 else 3338 init_expr &:= param_value; 3339 end if; 3340 init_expr &:= ";\n"; 3341 if current_object in globalInitalisations then 3342 globalInitalisations @:= [current_object] globalInitalisations[current_object] & init_expr; 3343 else 3344 globalInitalisations @:= [current_object] init_expr; 3345 end if; 3346 count_declarations(c_expr); 3347 end func; 3348 3349 3350const proc: process_interface_declaration (in reference: current_object, 3351 inout expr_type: c_expr) is func 3352 3353 local 3354 var reference: object_value is NIL; 3355 var category: valueCategory is category.value; 3356 begin 3357 c_expr.expr &:= type_name(getType(current_object)); 3358 c_expr.expr &:= " o_"; 3359 create_name(current_object, c_expr.expr); 3360 c_expr.expr &:= ";\n\n"; 3361 object_value := interfaceToStruct(current_object); 3362 valueCategory := category(object_value); 3363 if current_object not in const_table then 3364 const_table @:= [current_object] length(const_table); 3365 end if; 3366 global_init.expr &:= diagnosticLine(current_object); 3367 global_init.expr &:= "o_"; 3368 create_name(current_object, global_init.expr); 3369 global_init.expr &:= "=("; 3370 global_init.expr &:= type_name(getType(current_object)); 3371 global_init.expr &:= ")(itfCreate(itf["; 3372 global_init.expr &:= str(const_table[current_object]); 3373 global_init.expr &:= "]));\n"; 3374 count_declarations(c_expr); 3375 end func; 3376 3377 3378const proc: process_win_declaration (in reference: current_object, 3379 inout expr_type: c_expr) is func 3380 3381 begin 3382 if isVar(current_object) then 3383 c_expr.expr &:= "winType o_"; 3384 create_name(current_object, c_expr.expr); 3385 c_expr.expr &:= ";\n\n"; 3386 global_init.expr &:= diagnosticLine(current_object); 3387 global_init.expr &:= "o_"; 3388 create_name(current_object, global_init.expr); 3389 global_init.expr &:= "=drwCreate("; 3390 global_init.expr &:= windowLiteral(getValue(current_object, PRIMITIVE_WINDOW)); 3391 global_init.expr &:= ");\n"; 3392 count_declarations(c_expr); 3393 end if; 3394 end func; 3395 3396 3397const proc: process_process_declaration (in reference: current_object, 3398 inout expr_type: c_expr) is func 3399 3400 begin 3401 if isVar(current_object) then 3402 c_expr.expr &:= "processType o_"; 3403 create_name(current_object, c_expr.expr); 3404 c_expr.expr &:= "=NULL;\n\n"; 3405 count_declarations(c_expr); 3406 end if; 3407 end func; 3408 3409 3410const proc: process_prog_declaration (in reference: current_object, 3411 inout expr_type: c_expr) is func 3412 3413 begin 3414 if isVar(current_object) then 3415 c_expr.expr &:= "progType o_"; 3416 create_name(current_object, c_expr.expr); 3417 c_expr.expr &:= "=NULL;\n\n"; 3418 count_declarations(c_expr); 3419 end if; 3420 end func; 3421 3422 3423const proc: process_enum_declaration (in reference: current_object, 3424 inout expr_type: c_expr) is func 3425 3426 begin 3427 if isVar(current_object) or not isFunc(getType(current_object)) then 3428 if getType(current_object) = voidtype then 3429 c_expr.expr &:= "/* do not declare void variable or constant o_"; 3430 create_name2(current_object, c_expr.expr); 3431 c_expr.expr &:= " */\n\n"; 3432 else 3433 if not isVar(current_object) then 3434 c_expr.expr &:= "const "; 3435 end if; 3436 declare_type_if_necessary(getType(current_object), c_expr); 3437 c_expr.expr &:= type_name(getType(current_object)); 3438 c_expr.expr &:= " o_"; 3439 create_name(current_object, c_expr.expr); 3440 c_expr.expr &:= "="; 3441 c_expr.expr &:= enum_value(getValue(current_object, reference)); 3442 c_expr.expr &:= ";\n\n"; 3443 end if; 3444 end if; 3445 count_declarations(c_expr); 3446 end func; 3447 3448 3449const proc: process_enum_literal_declaration (in reference: current_object, 3450 inout expr_type: c_expr) is func 3451 3452 local 3453 var type: enum_type is void; 3454 begin 3455 enum_type := getType(current_object); 3456 if enum_type = voidtype then 3457 c_expr.expr &:= "/* do not declare: void o_4_empty */\n\n"; 3458 else 3459 if enum_type not in enum_literal then 3460 enum_literal @:= [enum_type] element_number_hash.EMPTY_HASH; 3461 end if; 3462 if current_object not in enum_literal[enum_type] then 3463 enum_literal[enum_type] @:= [current_object] length(enum_literal[enum_type]); 3464 end if; 3465 c_expr.expr &:= "const "; 3466 declare_type_if_necessary(enum_type, c_expr); 3467 c_expr.expr &:= type_name(enum_type); 3468 c_expr.expr &:= " o_"; 3469 create_name(current_object, c_expr.expr); 3470 c_expr.expr &:= "="; 3471 c_expr.expr &:= enum_value(current_object); 3472 c_expr.expr &:= ";\n\n"; 3473 end if; 3474 count_declarations(c_expr); 3475 end func; 3476 3477 3478const proc: print_parameter_list (in ref_list: formal_params, 3479 inout expr_type: c_expr) is func 3480 3481 local 3482 var reference: formal_param is NIL; 3483 var category: paramCategory is category.value; 3484 var boolean: first_element is TRUE; 3485 var type: param_type is void; 3486 var type: implementationType is void; 3487 begin 3488 for formal_param range formal_params do 3489 paramCategory := category(formal_param); 3490 if paramCategory <> SYMBOLOBJECT then 3491 if first_element then 3492 first_element := FALSE; 3493 else 3494 c_expr.expr &:= " printf(\", \");\n"; 3495 end if; 3496 param_type := getType(formal_param); 3497 if param_type in implements then 3498 c_expr.expr &:= " /*# "; 3499 for implementationType range implements[param_type] do 3500 c_expr.expr &:= type_name2(implementationType); 3501 c_expr.expr &:= " "; 3502 end for; 3503 c_expr.expr &:= " */ "; 3504 end if; 3505 c_expr.expr &:= "printf("; 3506 c_expr.expr &:= c_literal(str(paramCategory) & " "); 3507 c_expr.expr &:= "); "; 3508 if param_type in typeCategory then 3509 case typeCategory[param_type] of 3510 when {INTOBJECT}: 3511 c_expr.expr &:= "printf(\"intType \"); "; 3512 c_expr.expr &:= "printf(\"%ld\", "; 3513 when {FLOATOBJECT}: 3514 c_expr.expr &:= "printf(\"floatType \"); "; 3515 c_expr.expr &:= "printf(\"%f\", "; 3516 when {CHAROBJECT}: 3517 c_expr.expr &:= "printf(\"charType \"); "; 3518 c_expr.expr &:= "printf(\"%c\", "; 3519 when {STRIOBJECT}: 3520 c_expr.expr &:= "printf(\"striType \"); "; 3521 c_expr.expr &:= "filPrint("; 3522 when {TYPEOBJECT}: 3523 c_expr.expr &:= "printf(\"typeType \"); "; 3524 c_expr.expr &:= "printf(\"%X\", "; 3525 otherwise: 3526 c_expr.expr &:= "printf(\""; 3527 c_expr.expr &:= type_name(param_type); 3528 c_expr.expr &:= " \"); "; 3529 c_expr.expr &:= "printf(\"%X\", "; 3530 end case; 3531 else 3532 c_expr.expr &:= "printf(\""; 3533 c_expr.expr &:= type_name(param_type); 3534 c_expr.expr &:= " \"); "; 3535 c_expr.expr &:= "printf(\"%X\", "; 3536 end if; 3537 if isPointerParam(formal_param) then 3538 c_expr.expr &:= "(o_"; 3539 create_name(formal_param, c_expr.expr); 3540 c_expr.expr &:= "?*o_"; 3541 create_name(formal_param, c_expr.expr); 3542 c_expr.expr &:= ":0)"; 3543 else 3544 c_expr.expr &:= "o_"; 3545 create_name(formal_param, c_expr.expr); 3546 end if; 3547 c_expr.expr &:= ");"; 3548 end if; 3549 end for; 3550 end func; 3551 3552 3553const proc: process_dynamic_parameter_list (in reference: function, 3554 in ref_list: actual_params, inout expr_type: c_expr) is func 3555 3556 local 3557 var ref_list: formal_params is ref_list.EMPTY; 3558 var reference: formal_param is NIL; 3559 var reference: actual_param is NIL; 3560 var category: formalCategory is category.value; 3561 var category: paramCategory is category.value; 3562 var boolean: first_element is TRUE; 3563 var integer: number is 0; 3564 begin 3565 formal_params := formalParams(function); 3566 for number range 1 to length(formal_params) do 3567 formal_param := formal_params[number]; 3568 actual_param := actual_params[number]; 3569 formalCategory := category(formal_param); 3570 paramCategory := category(actual_param); 3571 if paramCategory <> SYMBOLOBJECT and 3572 formalCategory <> SYMBOLOBJECT then 3573 if formalCategory = TYPEOBJECT then 3574 c_expr.expr &:= "/* attr t_"; 3575 c_expr.expr &:= str(typeNumber(getValue(formal_param, type))); 3576 c_expr.expr &:= " "; 3577 c_expr.expr &:= str(getValue(formal_param, type)); 3578 c_expr.expr &:= "*/ "; 3579 else 3580 if first_element then 3581 first_element := FALSE; 3582 else 3583 c_expr.expr &:= ", "; 3584 end if; 3585 if not isVar(actual_param) and isInOutParam(formal_param) then 3586 c_expr.expr &:= "/* SHOULD NOT HAPPEN &o_"; 3587 create_name(actual_param, c_expr.expr); 3588 c_expr.expr &:= " */"; 3589 elsif isPointerParam(actual_param) = isPointerParam(formal_param) then 3590 c_expr.expr &:= "o_"; 3591 create_name(actual_param, c_expr.expr); 3592 elsif isPointerParam(actual_param) and not isPointerParam(formal_param) then 3593 c_expr.expr &:= "*o_"; 3594 create_name(actual_param, c_expr.expr); 3595 else # if isVar(actual_param) or not isInOutParam(formal_param) then 3596 c_expr.expr &:= "&o_"; 3597 create_name(actual_param, c_expr.expr); 3598 end if; 3599 end if; 3600 end if; 3601 end for; 3602 end func; 3603 3604 3605const proc: process_dynamic_function_call (in reference: function, 3606 in ref_list: actual_params, in reference: interface_object, inout expr_type: c_expr) is func 3607 3608 local 3609 var expr_type: resultExpr is expr_type.value; 3610 begin 3611 resultExpr.currentFile := file(interface_object); 3612 resultExpr.currentLine := line(interface_object); 3613 resultExpr.expr &:= "o_"; 3614 create_name(function, resultExpr.expr); 3615 resultExpr.expr &:= "("; 3616 process_dynamic_parameter_list(function, actual_params, resultExpr); 3617 resultExpr.expr &:= ")"; 3618 if function in return_ref_to_value then 3619 c_expr.expr &:= "/* copy ref_to_value */ "; 3620 process_create_declaration(resultType(getType(interface_object)), global_c_expr); 3621 process_create_call(resultType(getType(interface_object)), 3622 resultExpr.expr, c_expr.expr); 3623 else 3624 c_expr.expr &:= resultExpr.expr; 3625 end if; 3626 c_expr.temp_decls &:= resultExpr.temp_decls; 3627 c_expr.temp_assigns &:= resultExpr.temp_assigns; 3628 c_expr.temp_frees &:= resultExpr.temp_frees; 3629 c_expr.temp_to_null &:= resultExpr.temp_to_null; 3630 end func; 3631 3632 3633const proc: process_dynamic_action_call (in reference: function, 3634 in ref_list: actual_params, in reference: interface_object, inout expr_type: c_expr) is func 3635 3636 local 3637 var expr_type: c_action_expr is expr_type.value; 3638 begin 3639 # c_expr.expr &:= "/* "; 3640 # c_expr.expr &:= str(getValue(function, ACTION)); 3641 # c_expr.expr &:= " */ "; 3642 c_action_expr.currentFile := file(interface_object); 3643 c_action_expr.currentLine := line(interface_object); 3644 c_action_expr.temp_num := c_expr.temp_num; 3645 process_action(function, actual_params, c_action_expr); 3646 c_expr.temp_num := c_action_expr.temp_num; 3647 c_expr.temp_decls &:= c_action_expr.temp_decls; 3648 c_expr.temp_assigns &:= c_action_expr.temp_assigns; 3649 c_expr.temp_frees &:= c_action_expr.temp_frees; 3650 c_expr.temp_to_null &:= c_action_expr.temp_to_null; 3651 if c_action_expr.result_expr <> "" then 3652 c_expr.expr &:= c_action_expr.result_expr; 3653 else 3654 if isVarfunc(getType(interface_object)) or 3655 getType(interface_object) = proctype then 3656 c_expr.expr &:= c_action_expr.expr; 3657 else 3658 c_expr.expr &:= "/* copy ref_to_value */ "; 3659 process_create_declaration(resultType(getType(interface_object)), global_c_expr); 3660 process_create_call(resultType(getType(interface_object)), 3661 c_action_expr.expr, c_expr.expr); 3662 end if; 3663 end if; 3664 end func; 3665 3666 3667const proc: process_dynamic_call (in reference: function, 3668 in ref_list: actual_params, in reference: interface_object, 3669 inout expr_type: c_expr) is func 3670 3671 local 3672 var category: objectCategory is category.value; 3673 var expr_type: resultExpr is expr_type.value; 3674 begin 3675 if function <> NIL then 3676 c_expr.expr &:= diagnosticLine(interface_object); 3677 objectCategory := category(function); 3678 if objectCategory = BLOCKOBJECT then 3679 if resultType(getType(interface_object)) <> voidtype then 3680 c_expr.expr &:= "return "; 3681 end if; 3682 if function in function_declared or resultVar(function) <> NIL then 3683 process_dynamic_function_call(function, actual_params, interface_object, c_expr); 3684 else 3685 process_inline(function, actual_params, c_expr); 3686 end if; 3687 c_expr.expr &:= ";\n"; 3688 elsif objectCategory = ACTOBJECT then 3689 if resultType(getType(interface_object)) <> voidtype then 3690 c_expr.expr &:= "return "; 3691 if isVarfunc(getType(interface_object)) then 3692 c_expr.expr &:= "&("; 3693 end if; 3694 end if; 3695 process_dynamic_action_call(function, actual_params, interface_object, c_expr); 3696 if resultType(getType(interface_object)) <> voidtype then 3697 if isVarfunc(getType(interface_object)) then 3698 c_expr.expr &:= ")"; 3699 end if; 3700 c_expr.expr &:= ";\n"; 3701 end if; 3702 elsif objectCategory = INTOBJECT or 3703 objectCategory = BIGINTOBJECT or 3704 objectCategory = FLOATOBJECT or 3705 objectCategory = CHAROBJECT or 3706 objectCategory = STRIOBJECT or 3707 objectCategory = BSTRIOBJECT or 3708 objectCategory = ARRAYOBJECT or 3709 objectCategory = STRUCTOBJECT or 3710 objectCategory = SETOBJECT or 3711 objectCategory = WINOBJECT or 3712 objectCategory = PROCESSOBJECT or 3713 objectCategory = CONSTENUMOBJECT then 3714 c_expr.expr &:= "return "; 3715 getAnyParamToExpr(function, resultExpr); 3716 process_create_declaration(getType(function), global_c_expr); 3717 process_create_call(getType(function), 3718 resultExpr.expr, c_expr.expr); 3719 c_expr.expr &:= ";\n"; 3720 else 3721 c_expr.expr &:= "/* "; 3722 c_expr.expr &:= str(objectCategory); 3723 c_expr.expr &:= " */\n"; 3724 end if; 3725 else 3726 c_expr.expr &:= "/* NOT FOUND */\n"; 3727 c_expr.expr &:= diagnosticLine(interface_object); 3728 c_expr.expr &:= "raiseError(ACTION_ERROR);\n"; 3729 end if; 3730 end func; 3731 3732 3733const proc: process_dynamic_condition (in reference: current_object, 3734 inout ref_list: formal_params, in var integer: paramNum, 3735 inout expr_type: c_expr) is forward; 3736 3737 3738const proc: process_dynamic_param_implements (in reference: current_object, 3739 inout ref_list: formal_params, in var integer: paramNum, 3740 in type: param_type, inout expr_type: c_expr) is func 3741 3742 local 3743 var reference: formal_param is NIL; 3744 var type: implementationType is void; 3745 var bitset: usedCaseLabels is {}; 3746 begin 3747 formal_param := formal_params[paramNum]; 3748 c_expr.expr &:= diagnosticLine(current_object); 3749 c_expr.expr &:= "switch (((interfaceType) "; 3750 if isPointerParam(formal_param) then 3751 c_expr.expr &:= "*o_"; 3752 else 3753 c_expr.expr &:= "o_"; 3754 end if; 3755 create_name(formal_param, c_expr.expr); 3756 c_expr.expr &:= ")->type_num) {\n"; 3757 for implementationType range implements[param_type] do 3758 if typeNumber(implementationType) not in usedCaseLabels then 3759 c_expr.expr &:= "case "; 3760 c_expr.expr &:= str(typeNumber(implementationType)); 3761 c_expr.expr &:= "/*"; 3762 c_expr.expr &:= str(implementationType); 3763 c_expr.expr &:= "*/"; 3764 c_expr.expr &:= ":\n"; 3765 setType(formal_params[paramNum], implementationType); 3766 process_dynamic_condition(current_object, 3767 formal_params, paramNum, c_expr); 3768 setType(formal_params[paramNum], param_type); 3769 c_expr.expr &:= diagnosticLine(current_object); 3770 c_expr.expr &:= "break;\n"; 3771 incl(usedCaseLabels, typeNumber(implementationType)); 3772 end if; 3773 end for; 3774 c_expr.expr &:= "default:\n"; 3775 c_expr.expr &:= diagnosticLine(current_object); 3776 c_expr.expr &:= "raiseError(ACTION_ERROR);\n"; 3777 (* 3778 c_expr.expr &:= diagnosticLine(current_object); 3779 c_expr.expr &:= "printf(\"type_num=%d\\n\", "; 3780 if isPointerParam(formal_param) then 3781 c_expr.expr &:= "((interfaceType) *o_"; 3782 else 3783 c_expr.expr &:= "((interfaceType) o_"; 3784 end if; 3785 create_name(formal_param, c_expr.expr); 3786 c_expr.expr &:= ")->type_num);\n"; 3787 c_expr.expr &:= diagnosticLine(current_object); 3788 c_expr.expr &:= "printf(\"o_"; 3789 create_name(current_object, c_expr.expr); 3790 c_expr.expr &:= "(\");\n"; 3791 c_expr.expr &:= diagnosticLine(current_object); 3792 print_parameter_list(formal_params, c_expr); 3793 c_expr.expr &:= "printf(\")\\n\");\n"; 3794 *) 3795 c_expr.expr &:= diagnosticLine(current_object); 3796 c_expr.expr &:= "break;\n"; 3797 c_expr.expr &:= "}\n"; 3798 end func; 3799 3800 3801const proc: process_dynamic_param_enumeration (in reference: current_object, 3802 inout ref_list: formal_params, in var integer: paramNum, 3803 in type: param_type, inout expr_type: c_expr) is func 3804 3805 local 3806 var reference: formal_param is NIL; 3807 var number_element_hash: enumsByIntValue is number_element_hash.value; 3808 var integer: intValueOfEnum is 0; 3809 var reference: enumLiteral is NIL; 3810 var reference: backupParam is NIL; 3811 begin 3812 formal_param := formal_params[paramNum]; 3813 c_expr.expr &:= diagnosticLine(current_object); 3814 c_expr.expr &:= "switch ("; 3815 if isPointerParam(formal_param) then 3816 c_expr.expr &:= "*o_"; 3817 create_name(formal_param, c_expr.expr); 3818 else 3819 c_expr.expr &:= "o_"; 3820 create_name(formal_param, c_expr.expr); 3821 end if; 3822 c_expr.expr &:= ") {\n"; 3823 enumsByIntValue := flip(enum_literal[param_type]); 3824 # Sort by integer values to always produce the same C code 3825 for intValueOfEnum range sort(keys(enumsByIntValue)) do 3826 c_expr.expr &:= diagnosticLine(current_object); 3827 c_expr.expr &:= "case "; 3828 c_expr.expr &:= str(intValueOfEnum); 3829 c_expr.expr &:= ": {\n"; 3830 # If the enums are correct there will only be one per integer value 3831 enumLiteral := enumsByIntValue[intValueOfEnum][1]; 3832 backupParam := formal_params[paramNum]; 3833 formal_params @:= [paramNum] enumLiteral; 3834 process_dynamic_condition(current_object, 3835 formal_params, paramNum, c_expr); 3836 formal_params @:= [paramNum] backupParam; 3837 c_expr.expr &:= diagnosticLine(current_object); 3838 c_expr.expr &:= "} break;\n"; 3839 end for; 3840 c_expr.expr &:= diagnosticLine(current_object); 3841 c_expr.expr &:= "default: {\n"; 3842 c_expr.expr &:= diagnosticLine(current_object); 3843 c_expr.expr &:= "raiseError(ACTION_ERROR);\n"; 3844 (* 3845 c_expr.expr &:= "printf(\"literal_num=%d\\n\", "; 3846 if isPointerParam(formal_param) then 3847 c_expr.expr &:= "*o_"; 3848 create_name(formal_param, c_expr.expr); 3849 else 3850 c_expr.expr &:= "o_"; 3851 create_name(formal_param, c_expr.expr); 3852 end if; 3853 c_expr.expr &:= ");\n"; 3854 c_expr.expr &:= "printf(\"o_"; 3855 create_name(current_object, c_expr.expr); 3856 c_expr.expr &:= "(\");\n"; 3857 print_parameter_list(formal_params, c_expr); 3858 c_expr.expr &:= "printf(\")\\n\");\n"; 3859 *) 3860 c_expr.expr &:= "} break;\n"; 3861 c_expr.expr &:= "}\n"; 3862 end func; 3863 3864 3865const proc: process_dynamic_condition (in reference: current_object, 3866 inout ref_list: formal_params, in var integer: paramNum, 3867 inout expr_type: c_expr) is func 3868 3869 local 3870 var reference: formal_param is NIL; 3871 var category: paramCategory is category.value; 3872 var type: param_type is void; 3873 var ref_list: param_list is ref_list.EMPTY; 3874 var reference: matched_object is NIL; 3875 begin 3876 incr(paramNum); 3877 if paramNum <= length(formal_params) then 3878 formal_param := formal_params[paramNum]; 3879 paramCategory := category(formal_param); 3880 if paramCategory <> SYMBOLOBJECT then 3881 param_type := getType(formal_param); 3882 if param_type in implements then 3883 process_dynamic_param_implements(current_object, 3884 formal_params, paramNum, param_type, c_expr); 3885 elsif param_type in enum_literal then 3886 process_dynamic_param_enumeration(current_object, 3887 formal_params, paramNum, param_type, c_expr); 3888 else 3889 process_dynamic_condition(current_object, 3890 formal_params, paramNum, c_expr); 3891 end if; 3892 else 3893 process_dynamic_condition(current_object, 3894 formal_params, paramNum, c_expr); 3895 end if; 3896 else 3897 param_list := formal_params; 3898 matched_object := match(prog, param_list); 3899 (* 3900 if matched_object = NIL then 3901 c_expr.expr &:= "printf(\"NOT FOUND:\\n\");\n"; 3902 for formal_param range formal_params do 3903 paramCategory := category(formal_param); 3904 if paramCategory <> SYMBOLOBJECT then 3905 param_type := getType(formal_param); 3906 if param_type in implements then 3907 c_expr.expr &:= "printf(\"type_num=%d\\n\", "; 3908 if isPointerParam(formal_param) then 3909 c_expr.expr &:= "((interfaceType) *o_"; 3910 else 3911 c_expr.expr &:= "((interfaceType) o_"; 3912 end if; 3913 create_name(formal_param, c_expr.expr); 3914 c_expr.expr &:= ")->type_num);\n"; 3915 elsif param_type in enum_literal then 3916 c_expr.expr &:= "printf(\"literal_num=%d\\n\", "; 3917 if isPointerParam(formal_param) then 3918 c_expr.expr &:= "*o_"; 3919 else 3920 c_expr.expr &:= "o_"; 3921 end if; 3922 create_name(formal_param, c_expr.expr); 3923 c_expr.expr &:= ");\n"; 3924 else 3925 c_expr.expr &:= "printf(\"other param_type\\n\");\n"; 3926 end if; 3927 else 3928 c_expr.expr &:= "printf(\"" <& striToUtf8(str(formal_param)) <& "\\n\");\n"; 3929 end if; 3930 end for; 3931 end if; 3932 *) 3933 process_dynamic_call(matched_object, formal_params, current_object, c_expr); 3934 end if; 3935 end func; 3936 3937 3938const proc: process_dynamic_decision (in reference: current_object, 3939 inout expr_type: c_expr) is func 3940 3941 local 3942 var expr_type: c_param_list is expr_type.value; 3943 var expr_type: c_func_body is expr_type.value; 3944 var type: object_type is void; 3945 var type: result_type is void; 3946 var ref_list: param_list is ref_list.EMPTY; 3947 begin 3948 object_type := getType(current_object); 3949 if isFunc(object_type) or isVarfunc(object_type) then 3950 result_type := resultType(object_type); 3951 if result_type not in typeCategory or typeCategory[result_type] <> TYPEOBJECT then 3952 declare_types_of_params(param_list, global_c_expr); 3953 c_expr.expr &:= diagnosticLine(current_object); 3954 c_expr.expr &:= "/* DYNAMIC */ static "; 3955 c_expr.expr &:= type_name(result_type); 3956 if isVarfunc(object_type) then 3957 c_expr.expr &:= " *o_"; 3958 else 3959 c_expr.expr &:= " o_"; 3960 end if; 3961 create_name(current_object, c_expr.expr); 3962 param_list := formalParams(current_object); 3963 c_expr.expr &:= " ("; 3964 process_param_list_declaration(param_list, c_param_list); 3965 c_expr.expr &:= c_param_list.expr; 3966 c_expr.expr &:= ")\n"; 3967 c_expr.expr &:= diagnosticLine(current_object); 3968 c_expr.expr &:= "{\n"; 3969 process_dynamic_condition(current_object, 3970 param_list, 0, c_func_body); 3971 appendWithDiagnostic(c_param_list.temp_decls, c_expr); 3972 appendWithDiagnostic(c_func_body.temp_decls, c_expr); 3973 c_expr.expr &:= c_param_list.temp_assigns; 3974 appendWithDiagnostic(c_func_body.temp_assigns, c_expr); 3975 c_expr.expr &:= c_func_body.expr; 3976 appendWithDiagnostic(c_param_list.temp_frees, c_expr); 3977 appendWithDiagnostic(c_func_body.temp_frees, c_expr); 3978 c_expr.expr &:= diagnosticLine(current_object); 3979 c_expr.expr &:= "}\n\n"; 3980 end if; 3981 end if; 3982 end func; 3983 3984 3985const proc: process_dynamic_decisions (inout expr_type: c_expr) is func 3986 3987 local 3988 var reference: current_object is NIL; 3989 begin 3990 for current_object range dynamic_functions do 3991 process_dynamic_decision(current_object, c_expr); 3992 end for; 3993 end func; 3994 3995 3996const proc: process_dynamic_declaration (in reference: current_object, 3997 inout expr_type: c_expr) is func 3998 3999 local 4000 var expr_type: c_param_list is expr_type.value; 4001 var type: object_type is void; 4002 var type: result_type is void; 4003 var ref_list: param_list is ref_list.EMPTY; 4004 begin 4005 object_type := getType(current_object); 4006 if isFunc(object_type) or isVarfunc(object_type) then 4007 result_type := resultType(object_type); 4008 if result_type not in typeCategory or typeCategory[result_type] <> TYPEOBJECT then 4009 dynamic_functions &:= make_list(current_object); 4010 declare_types_of_params(param_list, global_c_expr); 4011 c_expr.expr &:= "/* DYNAMIC */ static "; 4012 c_expr.expr &:= type_name(result_type); 4013 if isVarfunc(object_type) then 4014 c_expr.expr &:= " *o_"; 4015 else 4016 c_expr.expr &:= " o_"; 4017 end if; 4018 create_name(current_object, c_expr.expr); 4019 param_list := formalParams(current_object); 4020 c_expr.expr &:= " ("; 4021 process_param_list_declaration(param_list, c_param_list); 4022 c_expr.expr &:= c_param_list.expr; 4023 c_expr.expr &:= ");\n"; 4024 prototype_declared @:= [current_object] TRUE; 4025 end if; 4026 end if; 4027 end func; 4028 4029 4030const proc: process_hashcode (in reference: current_object, inout expr_type: c_expr) is func 4031 4032 local 4033 var ref_list: param_list is ref_list.EMPTY; 4034 var reference: expression is NIL; 4035 begin 4036 param_list := make_list(current_object); 4037 param_list &:= make_list(syobject(prog, "hashCode")); 4038 expression := matchExpr(prog, param_list); 4039 # TRACE_REF(expression); 4040 setCategory(expression, CALLOBJECT); 4041 process_expr(expression, c_expr); 4042 end func; 4043 4044 4045const func reference: keyCreateObj (in type: hash_type) is func 4046 4047 result 4048 var reference: keyCreate is NIL; 4049 local 4050 var ref_list: param_list is ref_list.EMPTY; 4051 begin 4052 param_list := make_list(typeObject(hash_type)); 4053 param_list &:= make_list(syobject(prog, ".")); 4054 param_list &:= make_list(syobject(prog, "keyCreate")); 4055 keyCreate := match(prog, param_list); 4056 keyCreate := getValue(keyCreate, reference); 4057 end func; 4058 4059 4060const func reference: keyCompareObj (in type: hash_type) is func 4061 4062 result 4063 var reference: keyCompare is NIL; 4064 local 4065 var ref_list: param_list is ref_list.EMPTY; 4066 begin 4067 param_list := make_list(typeObject(hash_type)); 4068 param_list &:= make_list(syobject(prog, ".")); 4069 param_list &:= make_list(syobject(prog, "keyCompare")); 4070 keyCompare := match(prog, param_list); 4071 keyCompare := getValue(keyCompare, reference); 4072 end func; 4073 4074 4075const func reference: dataCreateObj (in type: hash_type) is func 4076 4077 result 4078 var reference: dataCreate is NIL; 4079 local 4080 var ref_list: param_list is ref_list.EMPTY; 4081 begin 4082 param_list := make_list(typeObject(hash_type)); 4083 param_list &:= make_list(syobject(prog, ".")); 4084 param_list &:= make_list(syobject(prog, "dataCreate")); 4085 dataCreate := match(prog, param_list); 4086 dataCreate := getValue(dataCreate, reference); 4087 end func; 4088 4089 4090const func reference: dataCopyObj (in type: hash_type) is func 4091 4092 result 4093 var reference: dataCopy is NIL; 4094 local 4095 var ref_list: param_list is ref_list.EMPTY; 4096 begin 4097 param_list := make_list(typeObject(hash_type)); 4098 param_list &:= make_list(syobject(prog, ".")); 4099 param_list &:= make_list(syobject(prog, "dataCopy")); 4100 dataCopy := match(prog, param_list); 4101 dataCopy := getValue(dataCopy, reference); 4102 end func; 4103 4104 4105const proc: process_arr_cpy_declaration (in reference: current_object) is func 4106 4107 local 4108 var ref_list: params is ref_list.EMPTY; 4109 var type: base_type is void; 4110 var type: object_type is void; 4111 begin 4112 params := formalParams(current_object); 4113 if length(params) >= 1 then 4114 object_type := getType(params[1]); 4115 copyFunction @:= [object_type] current_object; 4116 typeCategory @:= [object_type] ARRAYOBJECT; 4117 base_type := base_type(object_type); 4118 if base_type <> void then 4119 if object_type not in array_element then 4120 array_element @:= [object_type] base_type; 4121 end if; 4122 if base_type not in array_type then 4123 array_type @:= [base_type] object_type; 4124 end if; 4125 end if; 4126 end if; 4127 end func; 4128 4129 4130const proc: process_arr_create_declaration (in reference: current_object) is func 4131 4132 local 4133 var ref_list: params is ref_list.EMPTY; 4134 var type: base_type is void; 4135 var type: object_type is void; 4136 begin 4137 params := formalParams(current_object); 4138 if length(params) >= 1 then 4139 object_type := getType(params[1]); 4140 createFunction @:= [object_type] current_object; 4141 typeCategory @:= [object_type] ARRAYOBJECT; 4142 base_type := base_type(object_type); 4143 if base_type <> void then 4144 if object_type not in array_element then 4145 array_element @:= [object_type] base_type; 4146 end if; 4147 if base_type not in array_type then 4148 array_type @:= [base_type] object_type; 4149 end if; 4150 end if; 4151 end if; 4152 end func; 4153 4154 4155const proc: process_arr_destr_declaration (in reference: current_object) is func 4156 4157 local 4158 var ref_list: params is ref_list.EMPTY; 4159 var type: base_type is void; 4160 var type: object_type is void; 4161 begin 4162 params := formalParams(current_object); 4163 if length(params) >= 1 then 4164 object_type := getType(params[1]); 4165 destrFunction @:= [object_type] current_object; 4166 typeCategory @:= [object_type] ARRAYOBJECT; 4167 base_type := base_type(object_type); 4168 if base_type <> void then 4169 if object_type not in array_element then 4170 array_element @:= [object_type] base_type; 4171 end if; 4172 if base_type not in array_type then 4173 array_type @:= [base_type] object_type; 4174 end if; 4175 end if; 4176 end if; 4177 end func; 4178 4179 4180const proc: process_arr_gen_declaration (in reference: current_object, 4181 inout expr_type: c_expr) is func 4182 4183 local 4184 var ref_list: params is ref_list.EMPTY; 4185 var type: result_type is void; 4186 var type: object_type is void; 4187 begin 4188 params := formalParams(current_object); 4189 if length(params) >= 1 then 4190 object_type := getType(params[1]); 4191 result_type := resultType(getType(current_object)); 4192 if object_type not in array_type then 4193 array_type @:= [object_type] result_type; 4194 end if; 4195 if result_type not in array_element then 4196 array_element @:= [result_type] object_type; 4197 end if; 4198 c_expr.expr &:= "/* ACTION ARR_GEN for type "; 4199 c_expr.expr &:= type_name2(result_type); 4200 c_expr.expr &:= " element is "; 4201 c_expr.expr &:= type_name2(object_type); 4202 c_expr.expr &:= " */\n\n"; 4203 end if; 4204 end func; 4205 4206 4207const proc: process_arr_idx_declaration (in reference: current_object, 4208 inout expr_type: c_expr) is func 4209 4210 local 4211 var ref_list: params is ref_list.EMPTY; 4212 var type: result_type is void; 4213 var type: object_type is void; 4214 begin 4215 params := formalParams(current_object); 4216 if length(params) >= 1 then 4217 object_type := getType(params[1]); 4218 result_type := resultType(getType(current_object)); 4219 if object_type not in array_element then 4220 array_element @:= [object_type] result_type; 4221 end if; 4222 if result_type not in array_type then 4223 array_type @:= [result_type] object_type; 4224 end if; 4225 c_expr.expr &:= "/* ACTION ARR_IDX for type "; 4226 c_expr.expr &:= type_name2(object_type); 4227 c_expr.expr &:= " element is "; 4228 c_expr.expr &:= type_name2(result_type); 4229 c_expr.expr &:= " */\n\n"; 4230 end if; 4231 end func; 4232 4233 4234const proc: process_arr_times_declaration (in reference: current_object, 4235 inout expr_type: c_expr) is func 4236 4237 local 4238 var string: diagnosticLine is ""; 4239 var ref_list: params is ref_list.EMPTY; 4240 var type: result_type is void; 4241 var type: object_type is void; 4242 begin 4243 diagnosticLine := diagnosticLine(current_object); 4244 params := formalParams(current_object); 4245 if length(params) >= 3 then 4246 object_type := getType(params[3]); 4247 result_type := resultType(getType(current_object)); 4248 if object_type in typeCategory and 4249 typeCategory[object_type] in simpleValueType then 4250 c_expr.expr &:= "/* times_"; 4251 c_expr.expr &:= str(typeNumber(result_type)); 4252 c_expr.expr &:= " not defined because arrTimes() is used instead. */\n"; 4253 else 4254 process_create_declaration(object_type, c_expr); 4255 c_expr.expr &:= diagnosticLine; 4256 # c_expr.expr &:= type_name(result_type); 4257 c_expr.expr &:= "static arrayType times_"; 4258 c_expr.expr &:= str(typeNumber(result_type)); 4259 c_expr.expr &:= " (intType n, const "; 4260 if useConstPrefix(object_type) then 4261 c_expr.expr &:= "const_"; 4262 end if; 4263 c_expr.expr &:= type_name(object_type); 4264 c_expr.expr &:= " b)\n"; 4265 c_expr.expr &:= diagnosticLine; 4266 prototype_declared @:= [current_object] TRUE; 4267 c_expr.expr &:= "{\n"; 4268 c_expr.expr &:= diagnosticLine; 4269 c_expr.expr &:= "arrayType a;\n"; 4270 c_expr.expr &:= diagnosticLine; 4271 c_expr.expr &:= "memSizeType i;\n"; 4272 c_expr.expr &:= diagnosticLine; 4273 c_expr.expr &:= "a=arrMalloc(1, n);\n"; 4274 c_expr.expr &:= diagnosticLine; 4275 c_expr.expr &:= "for (i = 0; i < (memSizeType)(n); i++) {\n"; 4276 c_expr.expr &:= diagnosticLine; 4277 c_expr.expr &:= "a->arr[i]"; 4278 c_expr.expr &:= select_value_from_rtlObjectStruct(object_type); 4279 c_expr.expr &:= "="; 4280 process_create_call(object_type, "b", c_expr.expr); 4281 c_expr.expr &:= ";\n"; 4282 c_expr.expr &:= diagnosticLine; 4283 c_expr.expr &:= "}\n"; 4284 c_expr.expr &:= diagnosticLine; 4285 c_expr.expr &:= "return a;\n"; 4286 c_expr.expr &:= diagnosticLine; 4287 c_expr.expr &:= "}\n"; 4288 c_expr.expr &:= noDiagnosticLine; 4289 c_expr.expr &:= "\n"; 4290 end if; 4291 end if; 4292 end func; 4293 4294 4295const proc: defineParam1TypeCategory (in reference: current_object, 4296 in category: param1Category) is func 4297 4298 local 4299 var ref_list: params is ref_list.EMPTY; 4300 var type: param1Type is void; 4301 begin 4302 params := formalParams(current_object); 4303 if length(params) >= 1 then 4304 param1Type := getType(params[1]); 4305 typeCategory @:= [param1Type] param1Category; 4306 end if; 4307 end func; 4308 4309 4310const proc: addImplementationToInterface (in type: implementationType, in type: interfaceType) is func 4311 4312 begin 4313 if interfaceType in implements then 4314 implements[interfaceType] &:= implementationType; 4315 else 4316 implements @:= [interfaceType] [] (implementationType); 4317 end if; 4318 if implementationType in interfaceOfType then 4319 interfaceOfType[implementationType] &:= interfaceType; 4320 else 4321 interfaceOfType @:= [implementationType] [] (interfaceType); 4322 end if; 4323 end func; 4324 4325 4326const proc: process_itf_cpy2_declaration (in reference: current_object, 4327 inout expr_type: c_expr) is func 4328 4329 local 4330 var ref_list: params is ref_list.EMPTY; 4331 var type: interfaceType is void; 4332 var type: implementationType is void; 4333 begin 4334 params := formalParams(current_object); 4335 if length(params) >= 1 then 4336 interfaceType := getType(params[1]); 4337 implementationType := getType(params[3]); 4338 addImplementationToInterface(implementationType, interfaceType); 4339 c_expr.expr &:= "/* itf_cpy2: "; 4340 c_expr.expr &:= type_name2(interfaceType); 4341 c_expr.expr &:= " := "; 4342 c_expr.expr &:= type_name2(implementationType); 4343 c_expr.expr &:= " */\n"; 4344 end if; 4345 end func; 4346 4347 4348const proc: process_itf_next_file_declaration (in reference: current_object) is func 4349 4350 local 4351 var type: object_type is void; 4352 begin 4353 object_type := getType(current_object); 4354 if isFunc(object_type) or isVarfunc(object_type) then 4355 fileInterfaceType := resultType(object_type); 4356 end if; 4357 end func; 4358 4359 4360const proc: process_hsh_cpy_declaration (in reference: current_object) is func 4361 4362 local 4363 var ref_list: params is ref_list.EMPTY; 4364 var type: hash_type is void; 4365 begin 4366 params := formalParams(current_object); 4367 if length(params) >= 1 then 4368 hash_type := getType(params[1]); 4369 copyFunction @:= [hash_type] current_object; 4370 typeCategory @:= [hash_type] HASHOBJECT; 4371 end if; 4372 end func; 4373 4374 4375const proc: process_hsh_create_declaration (in reference: current_object) is func 4376 4377 local 4378 var ref_list: params is ref_list.EMPTY; 4379 var type: object_type is void; 4380 begin 4381 params := formalParams(current_object); 4382 if length(params) >= 1 then 4383 object_type := getType(params[1]); 4384 createFunction @:= [object_type] current_object; 4385 typeCategory @:= [object_type] HASHOBJECT; 4386 end if; 4387 end func; 4388 4389 4390const proc: process_hsh_destr_declaration (in reference: current_object) is func 4391 4392 local 4393 var ref_list: params is ref_list.EMPTY; 4394 var type: object_type is void; 4395 begin 4396 params := formalParams(current_object); 4397 if length(params) >= 1 then 4398 object_type := getType(params[1]); 4399 destrFunction @:= [object_type] current_object; 4400 typeCategory @:= [object_type] HASHOBJECT; 4401 end if; 4402 end func; 4403 4404 4405const proc: addStructElem (in type: structType, in type: elemType, in reference: elementOfStruct) is func 4406 4407 local 4408 var integer: elementIndex is 0; 4409 var element_idx_hash: element_index is element_idx_hash.EMPTY_HASH; 4410 begin 4411 if structType in struct_element_idx then 4412 elementIndex := struct_size[structType]; 4413 struct_element_idx[structType] @:= [elementOfStruct] elementIndex; 4414 struct_element_type[structType] &:= elemType; 4415 struct_element[structType] &:= elementOfStruct; 4416 struct_size @:= [structType] succ(elementIndex); 4417 else 4418 struct_size @:= [structType] 1; 4419 element_index @:= [elementOfStruct] 0; 4420 struct_element_idx @:= [structType] element_index; 4421 struct_element_type @:= [structType] [0] elemType; 4422 struct_element @:= [structType] [0] elementOfStruct; 4423 end if; 4424 end func; 4425 4426 4427const proc: process_sct_cpy_declaration (in reference: current_object) is func 4428 4429 local 4430 var ref_list: params is ref_list.EMPTY; 4431 var type: sct_type is void; 4432 var type: meta_type is void; 4433 var type: interfaceType is void; 4434 var integer: structIndex is 0; 4435 begin 4436 params := formalParams(current_object); 4437 if length(params) >= 1 then 4438 sct_type := getType(params[1]); 4439 copyFunction @:= [sct_type] current_object; 4440 typeCategory @:= [sct_type] STRUCTOBJECT; 4441 if isDerived(sct_type) then 4442 meta_type := meta(sct_type); 4443 if meta_type in struct_element_idx then 4444 for structIndex range 0 to pred(struct_size[meta_type]) do 4445 addStructElem(sct_type, struct_element_type[meta_type][structIndex], 4446 struct_element[meta_type][structIndex]); 4447 end for; 4448 end if; 4449 if meta_type in interfaceOfType then 4450 for interfaceType range interfaceOfType[meta_type] do 4451 addImplementationToInterface(sct_type, interfaceType); 4452 end for; 4453 end if; 4454 end if; 4455 end if; 4456 end func; 4457 4458 4459const proc: process_sct_create_declaration (in reference: current_object) is func 4460 4461 local 4462 var ref_list: params is ref_list.EMPTY; 4463 var type: object_type is void; 4464 begin 4465 params := formalParams(current_object); 4466 object_type := getType(params[1]); 4467 createFunction @:= [object_type] current_object; 4468 typeCategory @:= [object_type] STRUCTOBJECT; 4469 end func; 4470 4471 4472const proc: process_sct_destr_declaration (in reference: current_object) is func 4473 4474 local 4475 var ref_list: params is ref_list.EMPTY; 4476 var type: object_type is void; 4477 begin 4478 params := formalParams(current_object); 4479 object_type := getType(params[1]); 4480 destrFunction @:= [object_type] current_object; 4481 typeCategory @:= [object_type] STRUCTOBJECT; 4482 end func; 4483 4484 4485const proc: process_sct_select_declaration (in reference: current_object, 4486 inout expr_type: c_expr) is func 4487 4488 local 4489 var ref_list: params is ref_list.EMPTY; 4490 var type: elemType is void; 4491 var type: structType is void; 4492 var reference: elementOfStruct is NIL; 4493 begin 4494 params := formalParams(current_object); 4495 if length(params) >= 3 and not isVar(params[1]) then 4496 structType := getType(params[1]); 4497 elementOfStruct := params[3]; 4498 elemType := resultType(getType(current_object)); 4499 addStructElem(structType, elemType, elementOfStruct); 4500 c_expr.expr &:= "/* struct element "; 4501 c_expr.expr &:= type_name2(elemType); 4502 c_expr.expr &:= " ** "; 4503 c_expr.expr &:= type_name2(structType); 4504 c_expr.expr &:= "->o_"; 4505 create_name2(elementOfStruct, c_expr.expr); 4506 c_expr.expr &:= " = "; 4507 c_expr.expr &:= str(struct_element_idx[structType][elementOfStruct]); 4508 c_expr.expr &:= " */\n"; 4509 end if; 4510 end func; 4511 4512 4513const proc: process_ref_select_declaration (in reference: current_object, 4514 inout expr_type: c_expr) is func 4515 4516 local 4517 var ref_list: params is ref_list.EMPTY; 4518 var type: elemType is void; 4519 var type: structType is void; 4520 var reference: elementOfStruct is NIL; 4521 begin 4522 params := formalParams(current_object); 4523 if length(params) >= 3 and not isVar(params[1]) then 4524 structType := getType(params[1]); 4525 elementOfStruct := params[3]; 4526 elemType := resultType(getType(current_object)); 4527 addStructElem(structType, elemType, elementOfStruct); 4528 c_expr.expr &:= "/* ref struct element "; 4529 c_expr.expr &:= type_name2(elemType); 4530 c_expr.expr &:= " ** "; 4531 c_expr.expr &:= type_name2(structType); 4532 c_expr.expr &:= "->o_"; 4533 create_name2(elementOfStruct, c_expr.expr); 4534 c_expr.expr &:= " = "; 4535 c_expr.expr &:= str(struct_element_idx[structType][elementOfStruct]); 4536 c_expr.expr &:= " */\n"; 4537 end if; 4538 end func; 4539 4540 4541const proc: process_var_action_declaration (in reference: current_object, 4542 inout expr_type: c_expr) is func 4543 4544 local 4545 var expr_type: c_value is expr_type.value; 4546 var string: valueName is ""; 4547 begin 4548 create_name(current_object, objNumber(current_object), valueName); 4549 processFuncValue(valueName, getType(current_object), current_object, c_value); 4550 c_expr.expr &:= c_value.temp_decls; 4551 global_init.expr &:= diagnosticLine(current_object); 4552 global_init.expr &:= c_value.temp_assigns; 4553 c_expr.expr &:= type_name(getType(current_object)); 4554 c_expr.expr &:= " o_"; 4555 create_name(current_object, c_expr.expr); 4556 c_expr.expr &:= " = "; 4557 c_expr.expr &:= c_value.expr; 4558 c_expr.expr &:= ";\n\n"; 4559 function_declared @:= [current_object] TRUE; 4560 end func; 4561 4562 4563const proc: process_action_declaration (in reference: current_object, 4564 inout expr_type: c_expr) is func 4565 4566 local 4567 var ACTION: current_action is action "PRC_NOOP"; 4568 var string: action_name is ""; 4569 begin 4570 if isVar(current_object) then 4571 process_var_action_declaration(current_object, c_expr); 4572 else 4573 current_action := getValue(current_object, ACTION); 4574 action_name := str(current_action); 4575 if action_name = "PRC_DYNAMIC" then 4576 process_dynamic_declaration(current_object, c_expr); 4577 count_declarations(c_expr); 4578 elsif action_name = "ACT_CPY" then 4579 defineParam1TypeCategory(current_object, ACTOBJECT); 4580 count_declarations(c_expr); 4581 elsif action_name = "ARR_CPY" then 4582 process_arr_cpy_declaration(current_object); 4583 count_declarations(c_expr); 4584 elsif action_name = "ARR_CREATE" then 4585 process_arr_create_declaration(current_object); 4586 count_declarations(c_expr); 4587 elsif action_name = "ARR_DESTR" then 4588 process_arr_destr_declaration(current_object); 4589 count_declarations(c_expr); 4590 elsif action_name = "ARR_GEN" then 4591 process_arr_gen_declaration(current_object, c_expr); 4592 count_declarations(c_expr); 4593 elsif action_name = "ARR_IDX" then 4594 process_arr_idx_declaration(current_object, c_expr); 4595 count_declarations(c_expr); 4596 elsif action_name = "ARR_TIMES" then 4597 process_arr_times_declaration(current_object, c_expr); 4598 count_declarations(c_expr); 4599 elsif action_name = "BIG_CPY" or action_name = "BIG_CREATE" then 4600 defineParam1TypeCategory(current_object, BIGINTOBJECT); 4601 count_declarations(c_expr); 4602 elsif action_name = "BLN_CPY" then 4603 defineParam1TypeCategory(current_object, BOOLOBJECT); 4604 count_declarations(c_expr); 4605 elsif action_name = "BST_CPY" or action_name = "BST_CREATE" then 4606 defineParam1TypeCategory(current_object, BSTRIOBJECT); 4607 count_declarations(c_expr); 4608 elsif action_name = "DRW_CPY" or action_name = "DRW_CREATE" then 4609 defineParam1TypeCategory(current_object, WINOBJECT); 4610 count_declarations(c_expr); 4611 elsif action_name = "PCS_CPY" or action_name = "PCS_CREATE" then 4612 defineParam1TypeCategory(current_object, PROCESSOBJECT); 4613 count_declarations(c_expr); 4614 elsif action_name = "ENU_CPY" then 4615 defineParam1TypeCategory(current_object, ENUMOBJECT); 4616 count_declarations(c_expr); 4617 elsif action_name = "FIL_CPY" or action_name = "FIL_CREATE" then 4618 defineParam1TypeCategory(current_object, FILEOBJECT); 4619 count_declarations(c_expr); 4620 elsif action_name = "FLT_CPY" or action_name = "FLT_CREATE" then 4621 defineParam1TypeCategory(current_object, FLOATOBJECT); 4622 count_declarations(c_expr); 4623 elsif action_name = "HSH_CPY" then 4624 process_hsh_cpy_declaration(current_object); 4625 count_declarations(c_expr); 4626 elsif action_name = "HSH_CREATE" then 4627 process_hsh_create_declaration(current_object); 4628 count_declarations(c_expr); 4629 elsif action_name = "HSH_DESTR" then 4630 process_hsh_destr_declaration(current_object); 4631 count_declarations(c_expr); 4632 elsif action_name = "INT_CPY" or action_name = "INT_CREATE" then 4633 defineParam1TypeCategory(current_object, INTOBJECT); 4634 count_declarations(c_expr); 4635 elsif action_name = "ITF_CPY" then 4636 defineParam1TypeCategory(current_object, INTERFACEOBJECT); 4637 count_declarations(c_expr); 4638 elsif action_name = "ITF_CPY2" then 4639 process_itf_cpy2_declaration(current_object, c_expr); 4640 count_declarations(c_expr); 4641 elsif action_name = "POL_CPY" or action_name = "POL_CREATE" then 4642 defineParam1TypeCategory(current_object, POLLOBJECT); 4643 count_declarations(c_expr); 4644 elsif action_name = "POL_NEXT_FILE" then 4645 process_itf_next_file_declaration(current_object); 4646 count_declarations(c_expr); 4647 elsif action_name = "PRG_CPY" or action_name = "PRG_CREATE" then 4648 defineParam1TypeCategory(current_object, PROGOBJECT); 4649 count_declarations(c_expr); 4650 elsif action_name = "REF_CPY" or action_name = "REF_CREATE" then 4651 defineParam1TypeCategory(current_object, REFOBJECT); 4652 count_declarations(c_expr); 4653 elsif action_name = "REF_SELECT" then 4654 process_ref_select_declaration(current_object, c_expr); 4655 count_declarations(c_expr); 4656 elsif action_name = "RFL_CPY" or action_name = "RFL_CREATE" then 4657 defineParam1TypeCategory(current_object, REFLISTOBJECT); 4658 count_declarations(c_expr); 4659 elsif action_name = "SCT_CPY" then 4660 process_sct_cpy_declaration(current_object); 4661 count_declarations(c_expr); 4662 elsif action_name = "SCT_CREATE" then 4663 process_sct_create_declaration(current_object); 4664 count_declarations(c_expr); 4665 elsif action_name = "SCT_DESTR" then 4666 process_sct_destr_declaration(current_object); 4667 count_declarations(c_expr); 4668 elsif action_name = "SCT_SELECT" then 4669 process_sct_select_declaration(current_object, c_expr); 4670 count_declarations(c_expr); 4671 elsif action_name = "SET_CPY" or action_name = "SET_CREATE" then 4672 defineParam1TypeCategory(current_object, SETOBJECT); 4673 count_declarations(c_expr); 4674 elsif action_name = "SOC_CPY" or action_name = "SOC_CREATE" then 4675 defineParam1TypeCategory(current_object, SOCKETOBJECT); 4676 count_declarations(c_expr); 4677 elsif action_name = "SQL_CPY_DB" or action_name = "SQL_CREATE_DB" then 4678 defineParam1TypeCategory(current_object, DATABASEOBJECT); 4679 count_declarations(c_expr); 4680 elsif action_name = "SQL_CPY_STMT" or action_name = "SQL_CREATE_STMT" then 4681 defineParam1TypeCategory(current_object, SQLSTMTOBJECT); 4682 count_declarations(c_expr); 4683(* 4684 else 4685 c_expr.expr &:= "/* ACTION "; 4686 c_expr.expr &:= action_name; 4687 c_expr.expr &:= " */"; 4688*) 4689 end if; 4690 end if; 4691 end func; 4692 4693 4694const proc: process_object_declaration (in reference: current_object, 4695 inout expr_type: c_expr) is func 4696 4697 local 4698 var category: objectCategory is category.value; 4699 begin 4700 objectCategory := category(current_object); 4701 if current_object = main_object then 4702 if category(current_object) = FORWARDOBJECT then 4703 process_library_initialisation(current_object, c_expr); 4704 else 4705 process_main_declaration(current_object, c_expr); 4706 end if; 4707 elsif objectCategory = BLOCKOBJECT then 4708 process_func_declaration(current_object, c_expr); 4709 elsif objectCategory = TYPEOBJECT then 4710 process_type_declaration(current_object, c_expr); 4711 elsif objectCategory = INTOBJECT then 4712 process_int_declaration(current_object, c_expr); 4713 elsif objectCategory = BIGINTOBJECT then 4714 process_bigint_declaration(current_object, c_expr); 4715 elsif objectCategory = CHAROBJECT then 4716 process_char_declaration(current_object, c_expr); 4717 elsif objectCategory = STRIOBJECT then 4718 process_stri_declaration(current_object, c_expr); 4719 elsif objectCategory = BSTRIOBJECT then 4720 process_bstri_declaration(current_object, c_expr); 4721 elsif objectCategory = FLOATOBJECT then 4722 process_float_declaration(current_object, c_expr); 4723 elsif objectCategory = REFOBJECT then 4724 process_reference_declaration(current_object, c_expr); 4725 elsif objectCategory = REFLISTOBJECT then 4726 process_ref_list_declaration(current_object, c_expr); 4727 elsif objectCategory = FILEOBJECT then 4728 process_file_declaration(current_object, c_expr); 4729 elsif objectCategory = SOCKETOBJECT then 4730 process_socket_declaration(current_object, c_expr); 4731 elsif objectCategory = POLLOBJECT then 4732 process_poll_declaration(current_object, c_expr); 4733 elsif objectCategory = ARRAYOBJECT then 4734 process_array_declaration(current_object, c_expr); 4735 elsif objectCategory = HASHOBJECT then 4736 process_hash_declaration(current_object, c_expr); 4737 elsif objectCategory = SETOBJECT then 4738 process_set_declaration(current_object, c_expr); 4739 elsif objectCategory = STRUCTOBJECT then 4740 process_struct_declaration(current_object, c_expr); 4741 elsif objectCategory = INTERFACEOBJECT then 4742 process_interface_declaration(current_object, c_expr); 4743 elsif objectCategory = WINOBJECT then 4744 process_win_declaration(current_object, c_expr); 4745 elsif objectCategory = PROCESSOBJECT then 4746 process_process_declaration(current_object, c_expr); 4747 elsif objectCategory = PROGOBJECT then 4748 process_prog_declaration(current_object, c_expr); 4749 elsif objectCategory = CONSTENUMOBJECT then 4750 process_enum_declaration(current_object, c_expr); 4751 elsif objectCategory = VARENUMOBJECT then 4752 process_enum_declaration(current_object, c_expr); 4753 elsif objectCategory = ENUMLITERALOBJECT then 4754 process_enum_literal_declaration(current_object, c_expr); 4755 elsif objectCategory = ACTOBJECT then 4756 process_action_declaration(current_object, c_expr); 4757 elsif objectCategory = FWDREFOBJECT then 4758 process_forward_declaration(current_object, c_expr); 4759 else 4760 c_expr.expr &:= "/* "; 4761 c_expr.expr &:= str(objectCategory); 4762 c_expr.expr &:= ": "; 4763 create_name2(current_object, c_expr.expr); 4764 c_expr.expr &:= " */\n"; 4765 end if; 4766 end func; 4767 4768 4769const proc: replaceLocalsFromOutside (in reference: local_function, 4770 inout reference: current_expression, in ref_list: local_objects, 4771 inout ref_list: additional_act_params, inout ref_list: additional_form_params) is func 4772 4773 local 4774 var ref_list: params is ref_list.EMPTY; 4775 var integer: paramNum is 0; 4776 var reference: aParam is NIL; 4777 var category: paramCategory is category.value; 4778 var reference: formalRefParam is NIL; 4779 begin 4780 params := getValue(current_expression, ref_list); 4781 for paramNum range 2 to length(params) do 4782 aParam := params[paramNum]; 4783 paramCategory := category(aParam); 4784 if paramCategory = MATCHOBJECT or paramCategory = CALLOBJECT then 4785 replaceLocalsFromOutside(local_function, aParam, local_objects, 4786 additional_act_params, additional_form_params); 4787 elsif paramCategory = LOCALVOBJECT or 4788 paramCategory = VALUEPARAMOBJECT or 4789 paramCategory = REFPARAMOBJECT or 4790 paramCategory = RESULTOBJECT then 4791 if aParam not in local_objects then 4792 if aParam in additional_act_params then 4793 formalRefParam := additional_form_params[pos(additional_act_params, aParam)]; 4794 elsif local_function in params_added and 4795 aParam in params_added[local_function] then 4796 formalRefParam := params_added[local_function][aParam]; 4797 else 4798 additional_act_params &:= make_list(aParam); 4799 formalRefParam := alloc(aParam); 4800 setCategory(formalRefParam, REFPARAMOBJECT); 4801 additional_form_params &:= make_list(formalRefParam); 4802 end if; 4803 params @:= [paramNum] formalRefParam; 4804 end if; 4805 end if; 4806 end for; 4807 setValue(current_expression, params); 4808 end func; 4809 4810 4811const proc: changeCallsOfLocalFunction (inout reference: current_expression, 4812 in reference: local_function, in ref_list: additional_params) is func 4813 4814 local 4815 var ref_list: params is ref_list.EMPTY; 4816 var integer: paramNum is 0; 4817 var reference: aParam is NIL; 4818 var category: paramCategory is category.value; 4819 begin 4820 params := getValue(current_expression, ref_list); 4821 for paramNum range 2 to length(params) do 4822 aParam := params[paramNum]; 4823 paramCategory := category(aParam); 4824 if paramCategory = MATCHOBJECT or paramCategory = CALLOBJECT then 4825 changeCallsOfLocalFunction(aParam, local_function, additional_params); 4826 elsif aParam = local_function then 4827 aParam := alloc(aParam); 4828 setCategory(aParam, MATCHOBJECT); 4829 setValue(aParam, make_list(params[paramNum]) & additional_params); 4830 params @:= [paramNum] aParam; 4831 setValue(current_expression, params); 4832 end if; 4833 end for; 4834 if params[1] = local_function then 4835 params &:= additional_params; 4836 setValue(current_expression, params); 4837 end if; 4838 end func; 4839 4840 4841const proc: changeCallsFromSubFunctions (in reference: parent_function, 4842 in reference: local_function, in ref_list: additional_params) is func 4843 4844 local 4845 var reference: parent_body is NIL; 4846 var reference: obj is NIL; 4847 begin 4848 if parent_function <> local_function then 4849 parent_body := body(parent_function); 4850 changeCallsOfLocalFunction(parent_body, local_function, additional_params); 4851 end if; 4852 for obj range localConsts(parent_function) do 4853 if category(obj) = BLOCKOBJECT then 4854 changeCallsFromSubFunctions(obj, local_function, additional_params); 4855 end if; 4856 end for; 4857 end func; 4858 4859 4860const proc: adjustParamsToAdd (in reference: local_function, 4861 inout ref_list: additional_act_params, inout ref_list: additional_form_params) is func 4862 4863 local 4864 var integer: paramNum is 0; 4865 var reference: actParam is NIL; 4866 var reference: formParam is NIL; 4867 begin 4868 if length(additional_act_params) <> 0 then 4869 if local_function not in params_added then 4870 params_added @:= [local_function] act_to_form_param_hash.value; 4871 end if; 4872 paramNum := 1; 4873 while paramNum <= length(additional_act_params) do 4874 actParam := additional_act_params[paramNum]; 4875 if actParam in params_added[local_function] then 4876 additional_act_params := additional_act_params[.. pred(paramNum)] & 4877 additional_act_params[succ(paramNum) ..]; 4878 additional_form_params := additional_form_params[.. pred(paramNum)] & 4879 additional_form_params[succ(paramNum) ..]; 4880 else 4881 incr(paramNum); 4882 end if; 4883 end while; 4884 for paramNum range 1 to length(additional_act_params) do 4885 actParam := additional_act_params[paramNum]; 4886 formParam := additional_form_params[paramNum]; 4887 if actParam not in params_added[local_function] then 4888 params_added[local_function] @:= [actParam] formParam; 4889 end if; 4890 end for; 4891 end if; 4892 end func; 4893 4894 4895const func boolean: fixLocalFunction (in reference: parent_function, 4896 in reference: local_function) is func 4897 4898 result 4899 var boolean: fix_done is FALSE; 4900 local 4901 var reference: body_expression is NIL; 4902 var category: bodyCategory is category.value; 4903 var ref_list: local_objects is ref_list.EMPTY; 4904 var ref_list: additional_act_params is ref_list.EMPTY; 4905 var ref_list: additional_form_params is ref_list.EMPTY; 4906 begin 4907 body_expression := body(local_function); 4908 bodyCategory := category(body_expression); 4909 if bodyCategory = MATCHOBJECT or bodyCategory = CALLOBJECT then 4910 local_objects := formalParams(local_function) & localVars(local_function) & 4911 make_list(resultVar(local_function)); 4912 replaceLocalsFromOutside(local_function, body_expression, local_objects, 4913 additional_act_params, additional_form_params); 4914 adjustParamsToAdd(local_function, additional_act_params, additional_form_params); 4915 if length(additional_act_params) <> 0 then 4916 setFormalParams(local_function, formalParams(local_function) & additional_form_params); 4917 changeCallsOfLocalFunction(body_expression, local_function, additional_form_params); 4918 changeCallsFromSubFunctions(parent_function, local_function, additional_act_params); 4919 fix_done := TRUE; 4920 end if; 4921 end if; 4922 end func; 4923 4924 4925const proc: processLocalFunctions (in reference: current_object) is func 4926 4927 local 4928 var ref_list: objects is ref_list.EMPTY; 4929 var reference: obj is NIL; 4930 var boolean: fix_done is FALSE; 4931 begin 4932 objects := localConsts(current_object); 4933 repeat 4934 fix_done := FALSE; 4935 for obj range objects do 4936 if category(obj) = BLOCKOBJECT then 4937 processLocalFunctions(obj); 4938 if fixLocalFunction(current_object, obj) then 4939 fix_done := TRUE; 4940 end if; 4941 end if; 4942 end for; 4943 until not fix_done; 4944 end func; 4945 4946 4947const proc: addTypeCategoryForLocalVars (in reference: function) is func 4948 4949 local 4950 var ref_list: objects is ref_list.EMPTY; 4951 var reference: obj is NIL; 4952 var reference: object_value is NIL; 4953 var type: objectType is void; 4954 var category: valueCategory is category.value; 4955 begin 4956 objects := localVars(function); 4957 for obj range objects do 4958 object_value := getValue(obj, reference); 4959 valueCategory := category(object_value); 4960 objectType := getType(obj); 4961 if objectType = getType(object_value) and objectType not in typeCategory then 4962 typeCategory @:= [objectType] valueCategory; 4963 end if; 4964 end for; 4965 end func; 4966 4967 4968const proc: process_local_consts (in reference: function, 4969 inout expr_type: c_expr) is func 4970 4971 local 4972 var ref_list: objects is ref_list.EMPTY; 4973 var reference: obj is NIL; 4974 begin 4975 addTypeCategoryForLocalVars(function); 4976 processLocalFunctions(function); 4977 objects := localConsts(function); 4978 for obj range objects do 4979 if category(obj) <> FWDREFOBJECT then 4980 declare_type_if_necessary(getType(obj), global_c_expr); 4981 end if; 4982 process_object_declaration(obj, c_expr); 4983 end for; 4984 end func; 4985 4986 4987const proc: process_object (in reference: current_object) is func 4988 4989 local 4990 var expr_type: c_expr is expr_type.value; 4991 begin 4992 write_object_declaration := TRUE; 4993 process_object_declaration(current_object, c_expr); 4994 write(c_prog, global_c_expr.expr); 4995 if write_object_declaration then 4996 # writeln(c_prog, "/* " <& countDeclarations <& " */"); 4997 write(c_prog, c_expr.expr); 4998(* 4999 else 5000 write(c_prog, "#ifdef WRITE_OBJECT_DECLARATION\n"); 5001 write(c_prog, c_expr.expr); 5002 write(c_prog, "#endif\n"); 5003*) 5004 end if; 5005 flush(c_prog); 5006 global_c_expr := expr_type.value; 5007 end func; 5008 5009 5010const proc: process_library_import_object (in reference: current_object) is func 5011 5012 local 5013 var expr_type: c_expr is expr_type.value; 5014 begin 5015 process_object_declaration(current_object, c_expr); 5016 global_c_expr := expr_type.value; 5017 end func; 5018 5019 5020const proc: write_file_head is func 5021 5022 begin 5023 writeln(c_prog, temp_marker); 5024 writeln(c_prog, "#include <stdlib.h>"); 5025 writeln(c_prog, "#include <stdio.h>"); 5026 writeln(c_prog, "#include <string.h>"); 5027 writeln(c_prog, "#include <math.h>"); 5028 writeln(c_prog, "#include <setjmp.h>"); 5029 writeln(c_prog, "#include <signal.h>"); 5030 writeln(c_prog, "typedef short int int16Type;"); 5031 writeln(c_prog, "typedef unsigned short int uint16Type;"); 5032 writeln(c_prog, "typedef " <& ccConf.INT32TYPE <& " int32Type;"); 5033 writeln(c_prog, "typedef " <& ccConf.UINT32TYPE <& " uint32Type;"); 5034 writeln(c_prog, "typedef " <& ccConf.INT64TYPE <& " int64Type;"); 5035 writeln(c_prog, "typedef " <& ccConf.UINT64TYPE <& " uint64Type;"); 5036 if ccConf.INT128TYPE <> "" then 5037 writeln(c_prog, "typedef " <& ccConf.INT128TYPE <& " int128Type;"); 5038 writeln(c_prog, "typedef " <& ccConf.UINT128TYPE <& " uint128Type;"); 5039 end if; 5040 if ccConf.TWOS_COMPLEMENT_INTTYPE then 5041 writeln(c_prog, "#define INT32TYPE_MIN ((int32Type) -2147483648" <& 5042 ccConf.INT32TYPE_LITERAL_SUFFIX <& ")"); 5043 else 5044 writeln(c_prog, "#define INT32TYPE_MIN (-2147483647" <& 5045 ccConf.INT32TYPE_LITERAL_SUFFIX <& ")"); 5046 end if; 5047 writeln(c_prog, "#define INT32TYPE_MAX 2147483647" <& 5048 ccConf.INT32TYPE_LITERAL_SUFFIX); 5049 if ccConf.INTTYPE_SIZE = 64 then 5050 writeln(c_prog, "#define INTTYPE_DECIMAL_SIZE 20"); 5051 writeln(c_prog, "typedef int64Type intType;"); 5052 writeln(c_prog, "typedef uint64Type uintType;"); 5053 if ccConf.INT128TYPE <> "" then 5054 writeln(c_prog, "typedef int128Type doubleIntType;"); 5055 writeln(c_prog, "typedef uint128Type doubleUintType;"); 5056 writeln(c_prog, "#define inIntTypeRange(num) ((doubleIntType) (intType) (num) == (num))"); 5057 end if; 5058 elsif ccConf.INTTYPE_SIZE = 32 then 5059 writeln(c_prog, "#define INTTYPE_DECIMAL_SIZE 11"); 5060 writeln(c_prog, "typedef int32Type intType;"); 5061 writeln(c_prog, "typedef uint32Type uintType;"); 5062 writeln(c_prog, "typedef int64Type doubleIntType;"); 5063 writeln(c_prog, "typedef uint64Type doubleUintType;"); 5064 writeln(c_prog, "#define inIntTypeRange(num) ((doubleIntType) (intType) (num) == (num))"); 5065 end if; 5066 writeln(c_prog, "typedef " <& ccConf.BOOLTYPE <& " boolType;"); 5067 writeln(c_prog, "typedef int enumType;"); 5068 if ccConf.FLOATTYPE_DOUBLE then 5069 writeln(c_prog, "typedef double floatType;"); 5070 else 5071 writeln(c_prog, "typedef float floatType;"); 5072 end if; 5073 writeln(c_prog, "typedef uint32Type charType;"); 5074 writeln(c_prog, "typedef int32Type scharType;"); 5075 writeln(c_prog, "typedef uint32Type strElemType;"); 5076 writeln(c_prog, "typedef uintType bitSetType;"); 5077 writeln(c_prog, "typedef uint" <& ccConf.POINTER_SIZE <& "Type memSizeType;"); 5078 writeln(c_prog, "typedef FILE *cFileType;"); 5079 writeln(c_prog, "typedef unsigned char *ustriType;"); 5080 writeln(c_prog, "typedef const unsigned char *const_ustriType;"); 5081 writeln(c_prog, "typedef struct striStruct {"); 5082 writeln(c_prog, " memSizeType size;"); 5083 if ccConf.WITH_STRI_CAPACITY then 5084 writeln(c_prog, " memSizeType capacity;"); 5085 end if; 5086 if ccConf.ALLOW_STRITYPE_SLICES then 5087 writeln(c_prog, " strElemType *mem;"); 5088 writeln(c_prog, " strElemType mem1[1];"); 5089 else 5090 writeln(c_prog, " strElemType mem[1];"); 5091 end if; 5092 writeln(c_prog, "} *striType;"); 5093 writeln(c_prog, "typedef const struct striStruct *const_striType;"); 5094 writeln(c_prog, "#define SIZ_STRI(len) ((sizeof(struct striStruct) - sizeof(strElemType)) + (len) * sizeof(strElemType))"); 5095 writeln(c_prog, "typedef struct bstriStruct {"); 5096 writeln(c_prog, " memSizeType size;"); 5097 if ccConf.ALLOW_BSTRITYPE_SLICES then 5098 writeln(c_prog, " unsigned char *mem;"); 5099 writeln(c_prog, " unsigned char mem1[1];"); 5100 else 5101 writeln(c_prog, " unsigned char mem[1];"); 5102 end if; 5103 writeln(c_prog, "} *bstriType;"); 5104 writeln(c_prog, "typedef const struct bstriStruct *const_bstriType;"); 5105 writeln(c_prog, "typedef struct fileStruct {"); 5106 writeln(c_prog, " cFileType cFile;"); 5107 writeln(c_prog, " uintType usage_count;"); 5108 writeln(c_prog, "} *fileType;"); 5109 writeln(c_prog, "typedef const struct fileStruct *const_fileType;"); 5110 writeln(c_prog, "typedef struct setStruct {"); 5111 writeln(c_prog, " intType min_position;"); 5112 writeln(c_prog, " intType max_position;"); 5113 writeln(c_prog, " bitSetType bitset[1];"); 5114 writeln(c_prog, "} *setType;"); 5115 writeln(c_prog, "typedef const struct setStruct *const_setType;"); 5116 writeln(c_prog, "typedef struct {"); 5117 writeln(c_prog, " int dummy;"); 5118 writeln(c_prog, "} bigIntRecord;"); 5119 writeln(c_prog, "typedef bigIntRecord *bigIntType;"); 5120 writeln(c_prog, "typedef const bigIntRecord *const_bigIntType;"); 5121 writeln(c_prog, "typedef struct pollStruct {"); 5122 writeln(c_prog, " int dummy;"); 5123 writeln(c_prog, "} *pollType;"); 5124 writeln(c_prog, "typedef const struct pollStruct *const_pollType;"); 5125 writeln(c_prog, "typedef struct winStruct {"); 5126 writeln(c_prog, " uintType usage_count;"); 5127 writeln(c_prog, "} *winType;"); 5128 writeln(c_prog, "typedef const struct winStruct *const_winType;"); 5129 writeln(c_prog, "typedef struct processStruct {"); 5130 writeln(c_prog, " uintType usage_count;"); 5131 writeln(c_prog, " fileType stdIn;"); 5132 writeln(c_prog, " fileType stdOut;"); 5133 writeln(c_prog, " fileType stdErr;"); 5134 writeln(c_prog, "} *processType;"); 5135 writeln(c_prog, "typedef const struct processStruct *const_processType;"); 5136 writeln(c_prog, "typedef struct databaseStruct {"); 5137 writeln(c_prog, " uintType usage_count;"); 5138 writeln(c_prog, "} *databaseType;"); 5139 writeln(c_prog, "typedef const struct databaseStruct *const_databaseType;"); 5140 writeln(c_prog, "typedef struct sqlStmtStruct {"); 5141 writeln(c_prog, " uintType usage_count;"); 5142 writeln(c_prog, "} *sqlStmtType;"); 5143 writeln(c_prog, "typedef const struct sqlStmtStruct *const_sqlStmtType;"); 5144 writeln(c_prog, "typedef struct progStruct {"); 5145 writeln(c_prog, " uintType usage_count;"); 5146 writeln(c_prog, "} *progType;"); 5147 writeln(c_prog, "typedef const struct progStruct *const_progType;"); 5148 writeln(c_prog, "typedef struct typeStruct *typeType;"); 5149 writeln(c_prog, "typedef const struct typeStruct *const_typeType;"); 5150 writeln(c_prog, "typedef struct rtlArrayStruct *arrayType;"); 5151 writeln(c_prog, "typedef const struct rtlArrayStruct *const_arrayType;"); 5152 writeln(c_prog, "typedef struct rtlHashStruct *hashType;"); 5153 writeln(c_prog, "typedef const struct rtlHashStruct *const_hashType;"); 5154 writeln(c_prog, "typedef struct rtlStructStruct *structType;"); 5155 writeln(c_prog, "typedef const struct rtlStructStruct *const_structType;"); 5156 writeln(c_prog, "typedef struct rtlStructStruct *interfaceType;"); 5157 writeln(c_prog, "typedef const struct rtlStructStruct *const_interfaceType;"); 5158 writeln(c_prog, "typedef struct objectStruct *objRefType;"); 5159 writeln(c_prog, "typedef const struct objectStruct *const_objRefType;"); 5160 writeln(c_prog, "typedef struct listStruct *listType;"); 5161 writeln(c_prog, "typedef const struct listStruct *const_listType;"); 5162 writeln(c_prog, "typedef objRefType (*actType) (listType);"); 5163 writeln(c_prog, "typedef int socketType;"); 5164 writeln(c_prog, "typedef uint" <& ccConf.GENERIC_SIZE <& "Type genericType;"); 5165 writeln(c_prog, "typedef union {"); 5166 writeln(c_prog, " genericType genericValue;"); 5167 writeln(c_prog, " typeType typeValue;"); 5168 writeln(c_prog, " boolType boolValue;"); 5169 writeln(c_prog, " enumType enumValue;"); 5170 writeln(c_prog, " intType intValue;"); 5171 writeln(c_prog, " bigIntType bigIntValue;"); 5172 writeln(c_prog, " floatType floatValue;"); 5173 writeln(c_prog, " charType charValue;"); 5174 writeln(c_prog, " striType striValue;"); 5175 writeln(c_prog, " bstriType bstriValue;"); 5176 writeln(c_prog, " fileType fileValue;"); 5177 writeln(c_prog, " socketType socketValue;"); 5178 writeln(c_prog, " pollType pollValue;"); 5179 writeln(c_prog, " setType setValue;"); 5180 writeln(c_prog, " winType winValue;"); 5181 writeln(c_prog, " processType processValue;"); 5182 writeln(c_prog, " progType progValue;"); 5183 writeln(c_prog, " databaseType databaseValue;"); 5184 writeln(c_prog, " sqlStmtType sqlStmtValue;"); 5185 writeln(c_prog, " arrayType arrayValue;"); 5186 writeln(c_prog, " hashType hashValue;"); 5187 writeln(c_prog, " structType structValue;"); 5188 writeln(c_prog, " interfaceType interfaceValue;"); 5189 writeln(c_prog, " objRefType objRefValue;"); 5190 writeln(c_prog, " listType listValue;"); 5191 writeln(c_prog, " actType actValue;"); 5192 writeln(c_prog, "} rtlValueUnion;"); 5193 writeln(c_prog, "typedef union {"); 5194 writeln(c_prog, " genericType genericValue;"); 5195 writeln(c_prog, " const_typeType typeValue;"); 5196 writeln(c_prog, " boolType boolValue;"); 5197 writeln(c_prog, " enumType enumValue;"); 5198 writeln(c_prog, " intType intValue;"); 5199 writeln(c_prog, " const_bigIntType bigIntValue;"); 5200 writeln(c_prog, " floatType floatValue;"); 5201 writeln(c_prog, " charType charValue;"); 5202 writeln(c_prog, " const_striType striValue;"); 5203 writeln(c_prog, " const_bstriType bstriValue;"); 5204 writeln(c_prog, " fileType fileValue;"); 5205 writeln(c_prog, " socketType socketValue;"); 5206 writeln(c_prog, " const_pollType pollValue;"); 5207 writeln(c_prog, " const_setType setValue;"); 5208 writeln(c_prog, " const_winType winValue;"); 5209 writeln(c_prog, " const_processType processValue;"); 5210 writeln(c_prog, " const_progType progValue;"); 5211 writeln(c_prog, " const_arrayType arrayValue;"); 5212 writeln(c_prog, " const_hashType hashValue;"); 5213 writeln(c_prog, " const_structType structValue;"); 5214 writeln(c_prog, " const_interfaceType interfaceValue;"); 5215 writeln(c_prog, " const_objRefType objRefValue;"); 5216 writeln(c_prog, " const_listType listValue;"); 5217 writeln(c_prog, " actType actValue;"); 5218 writeln(c_prog, "} const_rtlValueUnion;"); 5219 writeln(c_prog, "typedef struct rtlObjectStruct {"); 5220 writeln(c_prog, " rtlValueUnion value;"); 5221 writeln(c_prog, "} rtlObjectType;"); 5222 writeln(c_prog, "typedef const struct rtlObjectStruct const_rtlObjectType;"); 5223 writeln(c_prog, "typedef intType (*intfunctype)();"); 5224 writeln(c_prog, "typedef uint16Type categoryType;"); 5225 writeln(c_prog, "struct objectStruct {"); 5226 writeln(c_prog, " typeType type_of;"); 5227 writeln(c_prog, " uint" <& ccConf.POINTER_SIZE <& "Type descriptor;"); 5228 writeln(c_prog, " rtlValueUnion value;"); 5229 writeln(c_prog, " categoryType objcategory;"); 5230 writeln(c_prog, "};"); 5231 writeln(c_prog, "struct typeStruct {"); 5232 writeln(c_prog, " objRefType match_obj;"); 5233 writeln(c_prog, " typeType meta;"); 5234 writeln(c_prog, " typeType func_type;"); 5235 writeln(c_prog, " typeType varfunc_type;"); 5236 writeln(c_prog, " typeType result_type;"); 5237 writeln(c_prog, " boolType is_varfunc_type;"); 5238 writeln(c_prog, " void *interfaces;"); 5239 writeln(c_prog, " void *name;"); 5240 writeln(c_prog, "};"); 5241 writeln(c_prog, "struct listStruct {"); 5242 writeln(c_prog, " listType next;"); 5243 writeln(c_prog, " objRefType obj;"); 5244 writeln(c_prog, "};"); 5245 writeln(c_prog, "struct rtlArrayStruct {"); 5246 writeln(c_prog, " intType min_position;"); 5247 writeln(c_prog, " intType max_position;"); 5248 writeln(c_prog, " rtlObjectType arr[1];"); 5249 writeln(c_prog, "};"); 5250 writeln(c_prog, "struct rtlStructStruct {"); 5251 writeln(c_prog, " memSizeType usage_count;"); 5252 writeln(c_prog, " uint32Type type_num;"); 5253 writeln(c_prog, " rtlObjectType stru[1];"); 5254 writeln(c_prog, "};"); 5255 writeln(c_prog, "typedef struct freeListElemStruct {"); 5256 writeln(c_prog, " struct freeListElemStruct *next;"); 5257 writeln(c_prog, "} *freeListElemType;"); 5258 writeln(c_prog, "typedef struct rtlHashElemStruct *hashElemType;"); 5259 writeln(c_prog, "typedef const struct rtlHashElemStruct *const_hashElemType;"); 5260 writeln(c_prog, "typedef struct rtlHashElemStruct *const hashElemType_const;"); 5261 writeln(c_prog, "struct rtlHashElemStruct {"); 5262 writeln(c_prog, " hashElemType next_less;"); 5263 writeln(c_prog, " hashElemType next_greater;"); 5264 writeln(c_prog, " rtlObjectType key;"); 5265 writeln(c_prog, " rtlObjectType data;"); 5266 writeln(c_prog, "};"); 5267 writeln(c_prog, "struct rtlHashStruct {"); 5268 writeln(c_prog, " unsigned int bits;"); 5269 writeln(c_prog, " unsigned int mask;"); 5270 writeln(c_prog, " unsigned int table_size;"); 5271 writeln(c_prog, " memSizeType size;"); 5272 writeln(c_prog, " hashElemType table[1];"); 5273 writeln(c_prog, "};"); 5274 writeln(c_prog, "typedef struct hashElemListStruct {"); 5275 writeln(c_prog, " struct hashElemListStruct *next;"); 5276 writeln(c_prog, " hashElemType obj;"); 5277 writeln(c_prog, "} *hashElemListType;"); 5278 writeln(c_prog, "typedef union {"); 5279 writeln(c_prog, " uint32Type bits;"); 5280 writeln(c_prog, " float aFloat;"); 5281 writeln(c_prog, "} float2BitsUnion;"); 5282 writeln(c_prog, "typedef union {"); 5283 writeln(c_prog, " uint64Type bits;"); 5284 writeln(c_prog, " double aDouble;"); 5285 writeln(c_prog, "} double2BitsUnion;"); 5286 writeln(c_prog, "typedef intType (*compareType) (genericType, genericType);"); 5287 writeln(c_prog, "typedef genericType (*createFuncType) (genericType);"); 5288 writeln(c_prog, "typedef void (*destrFuncType) (genericType);"); 5289 writeln(c_prog, "typedef void (*copyFuncType) (genericType *, genericType);"); 5290 writeln(c_prog, "#define bitset_shift " <& log2(ccConf.INTTYPE_SIZE)); 5291 writeln(c_prog, "#define bitset_mask ((1 << bitset_shift) - 1)"); 5292 if ccConf.RSHIFT_DOES_SIGN_EXTEND then 5293 writeln(c_prog, "#define bitset_pos(number) ((number)>>bitset_shift)"); 5294 else 5295 writeln(c_prog, "#define bitset_pos(number) ((number)<0?~(~(number)>>bitset_shift):(number)>>bitset_shift)"); 5296 end if; 5297 writeln(c_prog, "striType arg_0;"); 5298 writeln(c_prog, "striType programName;"); 5299 writeln(c_prog, "striType programPath;"); 5300 writeln(c_prog, "arrayType arg_v;"); 5301 if ccConf.ALLOW_STRITYPE_SLICES then 5302 writeln(c_prog, "extern struct striStruct str[];"); 5303 else 5304 writeln(c_prog, "extern striType str[];"); 5305 end if; 5306 if ccConf.ALLOW_BSTRITYPE_SLICES then 5307 writeln(c_prog, "extern struct bstriStruct bst[];"); 5308 else 5309 writeln(c_prog, "extern bstriType bst[];"); 5310 end if; 5311 writeln(c_prog, "extern setType set[];"); 5312 writeln(c_prog, "extern typeType typ[];"); 5313 writeln(c_prog, "extern double2BitsUnion nanValue[];"); 5314 writeln(c_prog, "bigIntType *big;"); 5315 writeln(c_prog, "winType *win;"); 5316 writeln(c_prog, "arrayType *arr;"); 5317 writeln(c_prog, "structType *sct;"); 5318 writeln(c_prog, "hashType *hsh;"); 5319 writeln(c_prog, "interfaceType *itf;"); 5320 writeln(c_prog, "hashType *caseLabels;"); 5321 writeln(c_prog, "rtlValueUnion flt2int;"); 5322 writeln(c_prog, "extern memSizeType hs;"); 5323 writeln(c_prog); 5324 writeln(c_prog, "static const intType fact[] = {"); 5325 writeln(c_prog, " 1, 1, 2, 6, 24, 120, 720, 5040, 40320,"); 5326 writeln(c_prog, " 362880, 3628800, 39916800, 479001600,"); 5327 if ccConf.INTTYPE_SIZE = 64 then 5328 writeln(c_prog, " 6227020800, 87178291200, 1307674368000, 20922789888000,"); 5329 writeln(c_prog, " 355687428096000, 6402373705728000, 121645100408832000,"); 5330 writeln(c_prog, " 2432902008176640000"); 5331 end if; 5332 writeln(c_prog, " };"); 5333 if ccConf.FLOAT_ZERO_DIV_ERROR then 5334 writeln(c_prog, "extern const rtlValueUnion f_const[];"); 5335 writeln(c_prog, "#define NOT_A_NUMBER f_const[0].floatValue"); 5336 writeln(c_prog, "#define POSITIVE_INFINITY f_const[1].floatValue"); 5337 writeln(c_prog, "#define NEGATIVE_INFINITY f_const[2].floatValue"); 5338 else 5339 writeln(c_prog, "#define NOT_A_NUMBER ( 0.0 / 0.0)"); 5340 writeln(c_prog, "#define POSITIVE_INFINITY ( 1.0 / 0.0)"); 5341 writeln(c_prog, "#define NEGATIVE_INFINITY (-1.0 / 0.0)"); 5342 end if; 5343 writeln(c_prog, "extern const floatType negativeZero;"); 5344 writeln(c_prog, "extern struct fileStruct nullFileRecord;"); 5345 writeln(c_prog, "extern struct fileStruct stdinFileRecord;"); 5346 writeln(c_prog, "extern struct fileStruct stdoutFileRecord;"); 5347 writeln(c_prog, "extern struct fileStruct stderrFileRecord;"); 5348 writeln(c_prog, "typedef int errInfoType;"); 5349 writeln(c_prog, "#define OKAY_NO_ERROR 0"); 5350 writeln(c_prog, "#define MEMORY_ERROR 1"); 5351 writeln(c_prog, "#define NUMERIC_ERROR 2"); 5352 writeln(c_prog, "#define OVERFLOW_ERROR 3"); 5353 writeln(c_prog, "#define RANGE_ERROR 4"); 5354 writeln(c_prog, "#define INDEX_ERROR 5"); 5355 writeln(c_prog, "#define FILE_ERROR 6"); 5356 writeln(c_prog, "#define DATABSE_ERROR 7"); 5357 writeln(c_prog, "#define ACTION_ERROR 8"); 5358 writeln(c_prog, "#define CREATE_ERROR 9"); 5359 writeln(c_prog, "#define DESTROY_ERROR 10"); 5360 writeln(c_prog, "#define COPY_ERROR 11"); 5361 writeln(c_prog, "#define IN_ERROR 12"); 5362 writeln(c_prog, "static const char *exception_name[] = {"); 5363 writeln(c_prog, " \"OKAY_NO_ERROR\","); 5364 writeln(c_prog, " \"MEMORY_ERROR\","); 5365 writeln(c_prog, " \"NUMERIC_ERROR\","); 5366 writeln(c_prog, " \"OVERFLOW_ERROR\","); 5367 writeln(c_prog, " \"RANGE_ERROR\","); 5368 writeln(c_prog, " \"INDEX_ERROR\","); 5369 writeln(c_prog, " \"FILE_ERROR\","); 5370 writeln(c_prog, " \"DATABASE_ERROR\","); 5371 writeln(c_prog, " \"ACTION_ERROR\","); 5372 writeln(c_prog, " \"CREATE_ERROR\","); 5373 writeln(c_prog, " \"DESTROY_ERROR\","); 5374 writeln(c_prog, " \"COPY_ERROR\","); 5375 writeln(c_prog, " \"IN_ERROR\","); 5376 writeln(c_prog, " };"); 5377 writeln(c_prog, ccConf.MACRO_DEFS); 5378 writeln(c_prog, "#define ovfChk(x) unlikely(x)"); 5379 writeln(c_prog, "#define divChk(x) unlikely(x)"); 5380 writeln(c_prog, "#define numChk(x) unlikely(x)"); 5381 writeln(c_prog, "#define idxChk(x) unlikely(x)"); 5382 writeln(c_prog, "#define rngChk(x) unlikely(x)"); 5383 writeln(c_prog, "#define push_stack(stack,elem) \\"); 5384 writeln(c_prog, "{\\"); 5385 writeln(c_prog, " hashElemListType new_head = (hashElemListType)(malloc(sizeof(struct hashElemListStruct)));\\"); 5386 writeln(c_prog, " if (new_head == NULL) {\\"); 5387 writeln(c_prog, " raiseError(MEMORY_ERROR);\\"); 5388 writeln(c_prog, " } else {\\"); 5389 writeln(c_prog, " new_head->next = stack;\\"); 5390 writeln(c_prog, " new_head->obj = elem;\\"); 5391 writeln(c_prog, " stack = new_head;\\"); 5392 writeln(c_prog, " }\\"); 5393 writeln(c_prog, "}"); 5394 writeln(c_prog, "#define pop_stack(stack,elem) \\"); 5395 writeln(c_prog, "{\\"); 5396 writeln(c_prog, " hashElemListType old_head = stack;\\"); 5397 writeln(c_prog, " if (old_head == NULL) {\\"); 5398 writeln(c_prog, " elem = NULL;\\"); 5399 writeln(c_prog, " } else {\\"); 5400 writeln(c_prog, " stack = old_head->next;\\"); 5401 writeln(c_prog, " elem = old_head->obj;\\"); 5402 writeln(c_prog, " free(old_head);\\"); 5403 writeln(c_prog, " }\\"); 5404 writeln(c_prog, "}"); 5405 if ccConf.HAS_SIGSETJMP then 5406 writeln(c_prog, "#define do_setjmp(jump_buf) sigsetjmp(jump_buf, 1)"); 5407 writeln(c_prog, "typedef sigjmp_buf catch_type;"); 5408 else 5409 writeln(c_prog, "#define do_setjmp(jump_buf) setjmp(jump_buf)"); 5410 writeln(c_prog, "typedef jmp_buf catch_type;"); 5411 end if; 5412 writeln(c_prog, "catch_type *catch_stack;"); 5413 writeln(c_prog, "size_t catch_stack_pos;"); 5414 writeln(c_prog, "size_t max_catch_stack;"); 5415 writeln(c_prog, "const char *error_file = NULL;"); 5416 writeln(c_prog, "int error_line = 0;"); 5417 if profile_function then 5418 writeln(c_prog, "intType timMicroSec (void);"); 5419 writeln(c_prog, "static unsigned int profile_size;"); 5420 writeln(c_prog, "struct profileElement {"); 5421 writeln(c_prog, " intType time;"); 5422 writeln(c_prog, " intType count;"); 5423 writeln(c_prog, " intType depth;"); 5424 writeln(c_prog, " char *file;"); 5425 writeln(c_prog, " intType line;"); 5426 writeln(c_prog, " char *name;"); 5427 writeln(c_prog, "};"); 5428 writeln(c_prog, "static struct profileElement profile[];"); 5429 writeln(c_prog, "static void initProfile (void);"); 5430 writeln(c_prog, "static int cmpProfileElement (const void *elem1, const void *elem2)"); 5431 writeln(c_prog, "{"); 5432 writeln(c_prog, " int signumValue;"); 5433 writeln(c_prog, " if (((struct profileElement *) elem1)->time <"); 5434 writeln(c_prog, " ((struct profileElement *) elem2)->time) {"); 5435 writeln(c_prog, " signumValue = 1;"); 5436 writeln(c_prog, " } else if (((struct profileElement *) elem1)->time >"); 5437 writeln(c_prog, " ((struct profileElement *) elem2)->time) {"); 5438 writeln(c_prog, " signumValue = -1;"); 5439 writeln(c_prog, " } else if (((struct profileElement *) elem1)->count <"); 5440 writeln(c_prog, " ((struct profileElement *) elem2)->count) {"); 5441 writeln(c_prog, " signumValue = 1;"); 5442 writeln(c_prog, " } else if (((struct profileElement *) elem1)->count >"); 5443 writeln(c_prog, " ((struct profileElement *) elem2)->count) {"); 5444 writeln(c_prog, " signumValue = -1;"); 5445 writeln(c_prog, " } else {"); 5446 writeln(c_prog, " signumValue = strcmp(((struct profileElement *) elem1)->name,"); 5447 writeln(c_prog, " ((struct profileElement *) elem2)->name);"); 5448 writeln(c_prog, " }"); 5449 writeln(c_prog, " return signumValue;"); 5450 writeln(c_prog, "}"); 5451 end if; 5452 end func; 5453 5454 5455const proc: declareExtern (in string: prototype) is func 5456 5457 begin 5458 write(c_prog, "extern "); 5459 if declare_with_extern_c then 5460 write(c_prog, "\"C\" "); 5461 end if; 5462 writeln(c_prog, prototype); 5463 end func; 5464 5465 5466const proc: write_prototypes is func 5467 5468 begin 5469 act_prototypes(c_prog); 5470 arr_prototypes(c_prog); 5471 big_prototypes(c_prog); 5472 bin_prototypes(c_prog); 5473 bln_prototypes(c_prog); 5474 bst_prototypes(c_prog); 5475 chr_prototypes(c_prog); 5476 cmd_prototypes(c_prog); 5477 con_prototypes(c_prog); 5478 drw_prototypes(c_prog); 5479 fil_prototypes(c_prog); 5480 flt_prototypes(c_prog); 5481 gkb_prototypes(c_prog); 5482 hsh_prototypes(c_prog); 5483 int_prototypes(c_prog); 5484 itf_prototypes(c_prog); 5485 kbd_prototypes(c_prog); 5486 pcs_prototypes(c_prog); 5487 pol_prototypes(c_prog); 5488 prc_prototypes(c_prog); 5489 prg_prototypes(c_prog); 5490 ref_prototypes(c_prog); 5491 rfl_prototypes(c_prog); 5492 set_prototypes(c_prog); 5493 soc_prototypes(c_prog); 5494 sql_prototypes(c_prog); 5495 str_prototypes(c_prog); 5496 tim_prototypes(c_prog); 5497 typ_prototypes(c_prog); 5498 ut8_prototypes(c_prog); 5499 if ccConf.USE_WMAIN then 5500 declareExtern("arrayType getArgv (const int, wchar_t *const *const, striType *, striType *, striType *);"); 5501 else 5502 declareExtern("arrayType getArgv (const int, char *const *const, striType *, striType *, striType *);"); 5503 end if; 5504 declareExtern("intType heapsize (void);"); 5505 declareExtern("void setupStack (void);"); 5506 declareExtern("void setupFiles (void);"); 5507 declareExtern("void setupRand (void);"); 5508 declareExtern("void setupFloat (void);"); 5509 declareExtern("void setupBig (void);"); 5510 writeln(c_prog, "static void prcNoop (void) {}"); 5511 writeln(c_prog, "static void init_values (void);"); 5512 writeln(c_prog, "static void init_globals (void);"); 5513 declareExtern("void initPollOperations (const createFuncType, const destrFuncType);"); 5514 declareExtern("void genericCpy (genericType *const, const genericType);"); 5515 declareExtern("genericType genericCreate (genericType);"); 5516 declareExtern("void genericDestr (genericType);"); 5517 declareExtern("intType ptrCmp (const void *const, const void *const);"); 5518 declareExtern("intType ptrCmpGeneric (const genericType, const genericType);"); 5519 declareExtern("void ptrCpyGeneric (genericType *const, const genericType);"); 5520 declareExtern("genericType ptrCreateGeneric (const genericType);"); 5521 writeln(c_prog, "typedef void (*suspendInterprType) (int signalNum);"); 5522 declareExtern("void setupSignalHandlers (boolType, boolType, boolType, boolType, suspendInterprType);"); 5523 declareExtern("void triggerSigfpe (void);"); 5524 declareExtern("void rtlRaiseError (int, const char *, int) NORETURN;"); 5525 writeln(c_prog, "#define raiseError(num) rtlRaiseError(num, __FILE__, __LINE__)"); 5526 writeln(c_prog, "#define intRaiseError(num) (rtlRaiseError(num, __FILE__, __LINE__), 0)"); 5527 writeln(c_prog, "#define bigRaiseError(num) (bigIntType)(rtlRaiseError(num, __FILE__, __LINE__), NULL)"); 5528 writeln(c_prog, "#define strRaiseError(num) (striType)(rtlRaiseError(num, __FILE__, __LINE__), NULL)"); 5529 writeln(c_prog, "#define refRaiseError(num) (objRefType)(rtlRaiseError(num, __FILE__, __LINE__), NULL)"); 5530(* 5531 declareExtern("intType enuValue (objRefType a) {printf(\"enuValue\\n\");}"); 5532 declareExtern("intType enuValue (objRefType);"); 5533*) 5534 if trace_signal then 5535 writeln(c_prog, "#define filGetc(inFile) filGetcChkCtrlC(inFile)"); 5536 writeln(c_prog, "#define filGets(inFile, length) filGetsChkCtrlC(inFile, length)"); 5537 writeln(c_prog, "#define filHasNext(inFile) filHasNextChkCtrlC(inFile)"); 5538 writeln(c_prog, "#define filLineRead(inFile, terminationChar) filLineReadChkCtrlC(inFile, terminationChar)"); 5539 writeln(c_prog, "#define filWordRead(inFile, terminationChar) filWordReadChkCtrlC(inFile, terminationChar)"); 5540 else 5541 writeln(c_prog, "#define filGetc(inFile) (unlikely((inFile)->cFile==NULL)?intRaiseError(FILE_ERROR):fgetc((inFile)->cFile))"); 5542 end if; 5543 end func; 5544 5545 5546const proc: write_resize_catch_stack is func 5547 5548 begin 5549 writeln(c_prog); 5550 writeln(c_prog); 5551 writeln(c_prog, "static void resize_catch_stack (void)"); 5552 writeln(c_prog); 5553 writeln(c_prog, " {"); 5554 writeln(c_prog, " catch_type *resized_stack;"); 5555 writeln(c_prog); 5556 writeln(c_prog, " max_catch_stack += 128;"); 5557 writeln(c_prog, " resized_stack = (catch_type *)(realloc(catch_stack, max_catch_stack));"); 5558 writeln(c_prog, " if (resized_stack == NULL) {"); 5559 writeln(c_prog, " catch_stack_pos--;"); 5560 writeln(c_prog, " raiseError(MEMORY_ERROR);"); 5561 writeln(c_prog, " } else {"); 5562 writeln(c_prog, " catch_stack = resized_stack;"); 5563 writeln(c_prog, " }"); 5564 writeln(c_prog, " }"); 5565 writeln(c_prog); 5566 writeln(c_prog); 5567 end func; 5568 5569 5570const proc: initPollOperations (inout expr_type: c_expr) is func 5571 5572 begin 5573 if fileInterfaceType <> void then 5574 c_expr.expr &:= "initPollOperations((createFuncType)(&itfCreate), "; 5575 process_destr_declaration(fileInterfaceType, global_c_expr); 5576 c_expr.expr &:= "(destrFuncType)(&destr_"; 5577 c_expr.expr &:= str(typeNumber(fileInterfaceType)); 5578 c_expr.expr &:= "));\n"; 5579 end if; 5580 end func; 5581 5582 5583const func ref_list: determine_multiple_array_elements (in ref_list: array_list) is func 5584 5585 result 5586 var ref_list: elements_to_walk is ref_list.EMPTY; 5587 local 5588 var reference: element is NIL; 5589 var reference: previous_element is NIL; 5590 var reference: repeat_block_element is NIL; 5591 var integer: repeat_count is 0; 5592 begin 5593 for element range array_list do 5594 if previous_element <> NIL then 5595 if identical_values(previous_element, element) then 5596 if repeat_block_element = NIL then 5597 repeat_block_element := previous_element; 5598 repeat_count := 2; 5599 else 5600 incr(repeat_count); 5601 end if; 5602 else 5603 elements_to_walk &:= make_list(element); 5604 if repeat_block_element <> NIL then 5605 element_repeat_count @:= [repeat_block_element] repeat_count; 5606 repeat_block_element := NIL; 5607 end if; 5608 end if; 5609 else 5610 elements_to_walk &:= make_list(element); 5611 end if; 5612 previous_element := element; 5613 end for; 5614 if repeat_block_element <> NIL then 5615 element_repeat_count @:= [repeat_block_element] repeat_count; 5616 end if; 5617 end func; 5618 5619 5620const proc: walk_const_list (in ref_list: const_list, inout ref_list: sorted_list) is func 5621 5622 local 5623 var reference: current_object is NIL; 5624 var reference: struct_of_interface is NIL; 5625 var category: objectCategory is category.value; 5626 var ref_list: elements_to_walk is ref_list.EMPTY; 5627 begin 5628 for current_object range const_list do 5629 objectCategory := category(current_object); 5630 if objectCategory = BIGINTOBJECT then 5631 if getValue(current_object, bigInteger) not in bigint_const_table then 5632 bigint_const_table @:= [getValue(current_object, bigInteger)] length(bigint_const_table); 5633 end if; 5634 elsif objectCategory = STRIOBJECT then 5635 if getValue(current_object, string) not in stri_const_table then 5636 stri_const_table @:= [getValue(current_object, string)] length(stri_const_table); 5637 end if; 5638 elsif objectCategory = BSTRIOBJECT then 5639 if getValue(current_object, bstring) not in bstri_const_table then 5640 bstri_const_table @:= [getValue(current_object, bstring)] length(bstri_const_table); 5641 end if; 5642 elsif objectCategory = SETOBJECT then 5643 if getValue(current_object, bitset) not in set_const_table then 5644 set_const_table @:= [getValue(current_object, bitset)] length(set_const_table); 5645 end if; 5646 elsif objectCategory = WINOBJECT then 5647 if getValue(current_object, PRIMITIVE_WINDOW) not in win_const_table then 5648 win_const_table @:= [getValue(current_object, PRIMITIVE_WINDOW)] length(win_const_table); 5649 end if; 5650 elsif objectCategory = ARRAYOBJECT then 5651 if current_object not in const_table then 5652 const_table @:= [current_object] length(const_table); 5653 end if; 5654 elements_to_walk := determine_multiple_array_elements(arrayToList(current_object)); 5655 walk_const_list(elements_to_walk, sorted_list); 5656 sorted_list &:= make_list(current_object); 5657 elsif objectCategory = STRUCTOBJECT then 5658 if current_object not in const_table then 5659 const_table @:= [current_object] length(const_table); 5660 end if; 5661 walk_const_list(structToList(current_object), sorted_list); 5662 sorted_list &:= make_list(current_object); 5663 elsif objectCategory = HASHOBJECT then 5664 if current_object not in const_table then 5665 const_table @:= [current_object] length(const_table); 5666 end if; 5667 walk_const_list(hashKeysToList(current_object), sorted_list); 5668 walk_const_list(hashDataToList(current_object), sorted_list); 5669 sorted_list &:= make_list(current_object); 5670 elsif objectCategory = INTERFACEOBJECT then 5671 if current_object not in const_table then 5672 const_table @:= [current_object] length(const_table); 5673 end if; 5674 struct_of_interface := interfaceToStruct(current_object); 5675 if struct_of_interface not in const_table then 5676 const_table @:= [struct_of_interface] length(const_table); 5677 walk_const_list(structToList(struct_of_interface), sorted_list); 5678 sorted_list &:= make_list(struct_of_interface); 5679 elsif const_table[struct_of_interface] >= const_table[current_object] then 5680 sorted_list &:= make_list(struct_of_interface); 5681 end if; 5682 sorted_list &:= make_list(current_object); 5683 elsif objectCategory = MATCHOBJECT or objectCategory = ACTOBJECT or 5684 objectCategory = BLOCKOBJECT then 5685 if current_object not in const_table then 5686 const_table @:= [current_object] length(const_table); 5687 end if; 5688 sorted_list &:= make_list(current_object); 5689 end if; 5690 end for; 5691 end func; 5692 5693 5694const proc: prepare_func_literal (in reference: current_object, 5695 inout expr_type: c_expr) is func 5696 5697 local 5698 var expr_type: c_value is expr_type.value; 5699 var string: valueName is ""; 5700 begin 5701 create_name(current_object, objNumber(current_object), valueName); 5702 processFuncValue(valueName, getType(current_object), current_object, c_value); 5703 global_c_expr.expr &:= c_value.temp_decls; 5704 global_init.expr &:= diagnosticLine(current_object); 5705 global_init.expr &:= c_value.temp_assigns; 5706 function_declared @:= [current_object] TRUE; 5707 end func; 5708 5709 5710const proc: process_func_literal (in reference: current_object, 5711 inout expr_type: c_expr) is func 5712 5713 local 5714 var string: valueName is ""; 5715 begin 5716 create_name(current_object, objNumber(current_object), valueName); 5717 c_expr.expr &:= "&funcvalue_"; 5718 c_expr.expr &:= valueName; 5719 end func; 5720 5721 5722const proc: process_pollData_literal (in var pollData: aPollData, 5723 inout expr_type: c_expr) is func 5724 5725 begin 5726 c_expr.expr &:= "polEmpty()"; 5727 end func; 5728 5729 5730const proc: init_const_value (in reference: current_object, inout expr_type: c_expr) is func 5731 5732 local 5733 var category: objectCategory is category.value; 5734 begin 5735 objectCategory := category(current_object); 5736 if objectCategory = INTOBJECT then 5737 c_expr.expr &:= ".value.intValue="; 5738 c_expr.expr &:= integerLiteral(getValue(current_object, integer)); 5739 elsif objectCategory = BIGINTOBJECT then 5740 c_expr.expr &:= ".value.bigIntValue="; 5741 c_expr.expr &:= bigIntegerLiteral(getValue(current_object, bigInteger)); 5742 elsif objectCategory = CHAROBJECT then 5743 c_expr.expr &:= ".value.charValue="; 5744 c_expr.expr &:= charLiteral(getValue(current_object, char)); 5745 elsif objectCategory = STRIOBJECT then 5746 c_expr.expr &:= ".value.striValue="; 5747 c_expr.expr &:= stringLiteral(getValue(current_object, string)); 5748 elsif objectCategory = BSTRIOBJECT then 5749 c_expr.expr &:= ".value.bstriValue="; 5750 c_expr.expr &:= bstriLiteral(getValue(current_object, bstring)); 5751 elsif objectCategory = SETOBJECT then 5752 c_expr.expr &:= ".value.setValue="; 5753 c_expr.expr &:= bitsetLiteral(getValue(current_object, bitset)); 5754 elsif objectCategory = FLOATOBJECT then 5755 c_expr.expr &:= ".value.floatValue="; 5756 c_expr.expr &:= floatLiteral(getValue(current_object, float)); 5757 elsif objectCategory = REFOBJECT then 5758 c_expr.expr &:= ".value.objRefValue="; 5759 if getValue(current_object, reference) = NIL then 5760 c_expr.expr &:= "NULL"; 5761 else 5762 c_expr.expr &:= "(objRefType)(&("; 5763 process_expr(getValue(current_object, reference), c_expr); 5764 c_expr.expr &:= "))"; 5765 end if; 5766 elsif objectCategory = FILEOBJECT then 5767 c_expr.expr &:= ".value.fileValue=&"; 5768 c_expr.expr &:= lower(literal(getValue(current_object, clib_file))); 5769 c_expr.expr &:= "FileRecord"; 5770 elsif objectCategory = SOCKETOBJECT then 5771 c_expr.expr &:= ".value.intValue="; 5772 c_expr.expr &:= "-1"; 5773 elsif objectCategory = POLLOBJECT then 5774 c_expr.expr &:= ".value.pollValue="; 5775 process_pollData_literal(getValue(current_object, pollData), c_expr); 5776 elsif objectCategory = WINOBJECT then 5777 c_expr.expr &:= ".value.winValue=drwCreate("; 5778 c_expr.expr &:= windowLiteral(getValue(current_object, PRIMITIVE_WINDOW)); 5779 c_expr.expr &:= ")"; 5780 elsif objectCategory = PROCESSOBJECT then 5781 c_expr.expr &:= ".value.processValue="; 5782 c_expr.expr &:= "NULL"; 5783 elsif objectCategory = TYPEOBJECT then 5784 c_expr.expr &:= ".value.typeValue="; 5785 c_expr.expr &:= typeLiteral(getValue(current_object, type)); 5786 elsif objectCategory = CONSTENUMOBJECT then 5787 c_expr.expr &:= select_value_from_rtlObjectStruct( 5788 getType(getValue(current_object, reference))); 5789 c_expr.expr &:= "="; 5790 c_expr.expr &:= enum_value(getValue(current_object, reference)); 5791 elsif objectCategory = VARENUMOBJECT then 5792 c_expr.expr &:= select_value_from_rtlObjectStruct( 5793 getType(getValue(current_object, reference))); 5794 c_expr.expr &:= "="; 5795 c_expr.expr &:= enum_value(getValue(current_object, reference)); 5796 elsif objectCategory = ARRAYOBJECT then 5797 c_expr.expr &:= ".value.arrayValue="; 5798 c_expr.expr &:= "arr["; 5799 c_expr.expr &:= str(const_table[current_object]); 5800 c_expr.expr &:= "]"; 5801 elsif objectCategory = STRUCTOBJECT then 5802 c_expr.expr &:= ".value.structValue="; 5803 c_expr.expr &:= "sct["; 5804 c_expr.expr &:= str(const_table[current_object]); 5805 c_expr.expr &:= "]"; 5806 elsif objectCategory = HASHOBJECT then 5807 c_expr.expr &:= ".value.hashValue="; 5808 c_expr.expr &:= "hsh["; 5809 c_expr.expr &:= str(const_table[current_object]); 5810 c_expr.expr &:= "]"; 5811 elsif objectCategory = INTERFACEOBJECT then 5812 c_expr.expr &:= ".value.interfaceValue=itfCreate(itf["; 5813 c_expr.expr &:= str(const_table[current_object]); 5814 c_expr.expr &:= "])"; 5815 elsif objectCategory = MATCHOBJECT or objectCategory = ACTOBJECT or 5816 objectCategory = BLOCKOBJECT then 5817 c_expr.expr &:= ".value.genericValue="; 5818 process_func_literal(current_object, c_expr); 5819 else 5820 c_expr.expr &:= "/* "; 5821 c_expr.expr &:= str(objectCategory); 5822 c_expr.expr &:= " */"; 5823 end if; 5824 end func; 5825 5826 5827const func string: int32AsFourBytes (in integer: number) is func 5828 result 5829 var string: stri is ""; 5830 begin 5831 if ccConf.LITTLE_ENDIAN_INTTYPE then 5832 stri := bytes(number, UNSIGNED, LE, 4); 5833 else 5834 stri := bytes(number, UNSIGNED, BE, 4); 5835 end if; 5836 end func; 5837 5838 5839const func string: int64AsEightBytes (in integer: number) is func 5840 result 5841 var string: stri is ""; 5842 begin 5843 if ccConf.LITTLE_ENDIAN_INTTYPE then 5844 stri := bytes(number, UNSIGNED, LE, 8); 5845 else 5846 stri := bytes(number, UNSIGNED, BE, 8); 5847 end if; 5848 end func; 5849 5850 5851const func string: int64AsTwoInt32 (in bigInteger: number) is func 5852 5853 result 5854 var string: literals is ""; 5855 begin 5856 if ccConf.LITTLE_ENDIAN_INTTYPE then 5857 literals := str( number mod 16#100000000_) & 5858 "," & 5859 str((number >> 32) mod 16#100000000_) & 5860 ","; 5861 else 5862 literals := str((number >> 32) mod 16#100000000_) & 5863 "," & 5864 str( number mod 16#100000000_) & 5865 ","; 5866 end if; 5867 end func; 5868 5869 5870const proc: init_bigint_constants is func 5871 5872 local 5873 var bigint_index_hash: bigint_index is bigint_index_hash.EMPTY_HASH; 5874 var integer: number is 0; 5875 var bstring: bstri is bstring.value; 5876 begin 5877 bigint_index := flip(bigint_const_table); 5878 for number range sort(keys(bigint_index)) do 5879 bstri := bStriLe(bigint_index[number][1], TRUE); 5880 if bstri not in bstri_const_table then 5881 bstri_const_table @:= [bstri] length(bstri_const_table); 5882 end if; 5883 bigint_bstri_table @:= [number] bstri_const_table[bstri]; 5884 end for; 5885 end func; 5886 5887 5888const proc: assign_bigint_constants (inout expr_type: c_expr) is func 5889 5890 local 5891 var bigint_index_hash: bigint_index is bigint_index_hash.EMPTY_HASH; 5892 var bigInteger: big1 is bigInteger.value; 5893 var integer: number is 0; 5894 begin 5895 if length(bigint_const_table) = 0 then 5896 c_expr.expr &:= "big = NULL;\n"; 5897 else 5898 c_expr.expr &:= "big = (bigIntType *)(malloc("; 5899 c_expr.expr &:= str(length(bigint_const_table)); 5900 c_expr.expr &:= " * sizeof(bigIntType)));\n"; 5901 bigint_index := flip(bigint_const_table); 5902 for number range sort(keys(bigint_index)) do 5903 big1 := bigint_index[number][1]; 5904 c_expr.expr &:= "big["; 5905 c_expr.expr &:= str(number); 5906 c_expr.expr &:= "]=bigFromBStriLe("; 5907 if ccConf.ALLOW_BSTRITYPE_SLICES then 5908 c_expr.expr &:= "&"; 5909 end if; 5910 c_expr.expr &:= "bst["; 5911 c_expr.expr &:= str(bigint_bstri_table[number]); 5912 c_expr.expr &:= "], 1);"; 5913 if bitLength(big1) <= MAX_SHOWN_BIGINT_LITERAL_BITLENGTH then 5914 c_expr.expr &:= " /* "; 5915 c_expr.expr &:= str(big1); 5916 c_expr.expr &:= " */"; 5917 end if; 5918 c_expr.expr &:= "\n"; 5919 end for; 5920 end if; 5921 end func; 5922 5923 5924const proc: init_win_constants is func 5925 5926 local 5927 var win_index_hash: win_index is win_index_hash.EMPTY_HASH; 5928 var PRIMITIVE_WINDOW: win1 is PRIMITIVE_WINDOW.value; 5929 var integer: number is 0; 5930 var integer: line is 0; 5931 var integer: column is 0; 5932 var pixel: pix is pixel.value; 5933 var string: image is ""; 5934 var bstring: bImage is bstring.value; 5935 begin 5936 win_index := flip(win_const_table); 5937 for number range sort(keys(win_index)) do 5938 win1 := win_index[number][1]; 5939 if width(win1) <> 0 or height(win1) <> 0 then 5940 bImage := getImage(win1); 5941 if bImage not in bstri_const_table then 5942 bstri_const_table @:= [bImage] length(bstri_const_table); 5943 end if; 5944 win_bstri_table @:= [number] bstri_const_table[bImage]; 5945 end if; 5946 end for; 5947 end func; 5948 5949 5950const proc: assign_win_constants (inout expr_type: c_expr) is func 5951 5952 local 5953 var win_index_hash: win_index is win_index_hash.EMPTY_HASH; 5954 var PRIMITIVE_WINDOW: win1 is PRIMITIVE_WINDOW.value; 5955 var integer: number is 0; 5956 begin 5957 if length(win_const_table) = 0 then 5958 c_expr.expr &:= "win = NULL;\n"; 5959 else 5960 c_expr.expr &:= "win = (winType *)(malloc("; 5961 c_expr.expr &:= str(length(win_const_table)); 5962 c_expr.expr &:= " * sizeof(winType)));\n"; 5963 win_index := flip(win_const_table); 5964 for number range sort(keys(win_index)) do 5965 win1 := win_index[number][1]; 5966 c_expr.expr &:= "win["; 5967 c_expr.expr &:= str(number); 5968 c_expr.expr &:= "]="; 5969 if width(win1) = 0 and height(win1) = 0 then 5970 c_expr.expr &:= "drwEmpty();\n"; 5971 else 5972 c_expr.expr &:= "drwImage((int32Type *)(("; 5973 if ccConf.ALLOW_BSTRITYPE_SLICES then 5974 c_expr.expr &:= "&"; 5975 end if; 5976 c_expr.expr &:= "bst["; 5977 c_expr.expr &:= str(win_bstri_table[number]); 5978 c_expr.expr &:= "])->mem), "; 5979 c_expr.expr &:= str(width(win1)); 5980 c_expr.expr &:= ", "; 5981 c_expr.expr &:= str(height(win1)); 5982 c_expr.expr &:= ");\n"; 5983 end if; 5984 end for; 5985 end if; 5986 end func; 5987 5988 5989const proc: write_striChars (in string: striChars, inout expr_type: c_expr) is func 5990 local 5991 var integer: countChars is 0; 5992 var char: ch is ' '; 5993 begin 5994 if length(striChars) <> 0 then 5995 c_expr.expr &:= "static strElemType striChars["; 5996 c_expr.expr &:= str(length(striChars)); 5997 c_expr.expr &:= "]={\n"; 5998 for ch range striChars do 5999 c_expr.expr &:= c_literal(ch); 6000 c_expr.expr &:= ","; 6001 incr(countChars); 6002 if countChars = 20 then 6003 c_expr.expr &:= "\n"; 6004 countChars := 0; 6005 end if; 6006 end for; 6007 c_expr.expr &:= "};\n\n"; 6008 end if; 6009 end func; 6010 6011 6012const proc: write_str_table (in stri_index_hash: stri_index, 6013 in array integer: stringPosition, inout expr_type: c_expr) is func 6014 local 6015 var integer: number is 0; 6016 var string: stri is ""; 6017 begin 6018 c_expr.expr &:= "struct striStruct str[]={\n"; 6019 if length(stri_const_table) > 0 then 6020 for number range 0 to pred(length(stri_const_table)) do 6021 stri := stri_index[number][1]; 6022 c_expr.expr &:= "/* str["; 6023 c_expr.expr &:= str(number); 6024 c_expr.expr &:= "] */ {"; 6025 c_expr.expr &:= str(length(stri)); 6026 c_expr.expr &:= ","; 6027 if ccConf.WITH_STRI_CAPACITY then 6028 c_expr.expr &:= str(length(stri)); 6029 c_expr.expr &:= ","; 6030 end if; 6031 if stri = "" then 6032 c_expr.expr &:= "NULL"; 6033 else 6034 c_expr.expr &:= "&striChars["; 6035 c_expr.expr &:= str(pred(stringPosition[number])); 6036 c_expr.expr &:= "]"; 6037 end if; 6038 c_expr.expr &:= "},"; 6039 c_expr.expr &:= stringInComment(stri); 6040 c_expr.expr &:= "\n"; 6041 end for; 6042 else 6043 c_expr.expr &:= "/* dummy */ {0,"; 6044 if ccConf.WITH_STRI_CAPACITY then 6045 c_expr.expr &:= "0,"; 6046 end if; 6047 c_expr.expr &:= "NULL}"; 6048 end if; 6049 c_expr.expr &:= "};\n\n"; 6050 end func; 6051 6052 6053const proc: init_string_constants_with_slices (in stri_index_hash: stri_index, 6054 inout expr_type: c_expr) is func 6055 6056 local 6057 var stringLengthHash: stringLengths is stringLengthHash.value; 6058 var lengthToStriNumHash: lengthToStriNum is lengthToStriNumHash.value; 6059 var array integer: lengthList is 0 times 0; 6060 var integer: lengthIndex is 0; 6061 var integer: length is 0; 6062 var array integer: stringPosition is 0 times 0; 6063 var integer: number is 0; 6064 var string: stri is ""; 6065 var integer: combinedStriLength is 0; 6066 var string: striChars is ""; 6067 var integer: striPos is 0; 6068 var integer: striIndex is 0; 6069 var boolean: found is FALSE; 6070 begin 6071 stringPosition := [0 .. pred(length(stri_const_table))] times 0; 6072 for number range 0 to pred(length(stri_const_table)) do 6073 stringLengths @:= [number] length(stri_index[number][1]); 6074 end for; 6075 lengthToStriNum := flip(stringLengths); 6076 lengthList := sort(keys(lengthToStriNum)); 6077 for lengthIndex range maxIdx(lengthList) downto minIdx(lengthList) do 6078 length := lengthList[lengthIndex]; 6079 if length in lengthToStriNum then 6080 for number range lengthToStriNum[length] do 6081 stri := stri_index[number][1]; 6082 combinedStriLength +:= length(stri); 6083 striPos := pos(striChars, stri); 6084 if striPos = 0 then 6085 found := FALSE; 6086 if length(striChars) > length(stri) then 6087 striIndex := rpos(stri, striChars[length(striChars)]); 6088 while striIndex <> 0 and not found do 6089 if stri[.. striIndex] = striChars[succ(length(striChars) - striIndex) ..] then 6090 stringPosition[number] := succ(length(striChars) - striIndex); 6091 striChars &:= stri[succ(striIndex) ..]; 6092 found := TRUE; 6093 else 6094 striIndex := rpos(stri, striChars[length(striChars)], pred(striIndex)); 6095 end if; 6096 end while; 6097 end if; 6098 if not found then 6099 stringPosition[number] := succ(length(striChars)); 6100 striChars &:= stri; 6101 end if; 6102 else 6103 stringPosition[number] := striPos; 6104 end if; 6105 end for; 6106 end if; 6107 end for; 6108 write_striChars(striChars, c_expr); 6109 write_str_table(stri_index, stringPosition, c_expr); 6110 if SHOW_STATISTIC then 6111 writeln(combinedStriLength <& " chars in all strings"); 6112 writeln(length(striChars) <& " chars in string pool"); 6113 writeln(combinedStriLength - length(striChars) <& " chars of string memory saved"); 6114 end if; 6115 end func; 6116 6117 6118const proc: init_string_constants_no_slices (in stri_index_hash: stri_index, 6119 inout expr_type: c_expr) is func 6120 6121 local 6122 var integer: number is 0; 6123 var string: stri is ""; 6124 var char: ch is ' '; 6125 begin 6126 for number range sort(keys(stri_index)) do 6127 stri := stri_index[number][1]; 6128 c_expr.expr &:= "/* str["; 6129 c_expr.expr &:= str(number); 6130 c_expr.expr &:= "] */ static strElemType stri_"; 6131 c_expr.expr &:= str(number); 6132 c_expr.expr &:= "[]={"; 6133 if ccConf.POINTER_SIZE = 32 then 6134 c_expr.expr &:= str(length(stri)); 6135 c_expr.expr &:= ","; 6136 if ccConf.WITH_STRI_CAPACITY then 6137 c_expr.expr &:= str(length(stri)); 6138 c_expr.expr &:= ","; 6139 end if; 6140 elsif ccConf.POINTER_SIZE = 64 then 6141 c_expr.expr &:= int64AsTwoInt32(bigInteger(length(stri))); 6142 if ccConf.WITH_STRI_CAPACITY then 6143 c_expr.expr &:= int64AsTwoInt32(bigInteger(length(stri))); 6144 end if; 6145 end if; 6146 for ch range stri do 6147 c_expr.expr &:= c_literal(ch); 6148 c_expr.expr &:= ","; 6149 end for; 6150 c_expr.expr &:= "};\n"; 6151 end for; 6152 c_expr.expr &:= "striType str[]={\n"; 6153 if length(stri_const_table) > 0 then 6154 for number range sort(keys(stri_index)) do 6155 stri := stri_index[number][1]; 6156 c_expr.expr &:= "(striType) stri_"; 6157 c_expr.expr &:= str(number); 6158 c_expr.expr &:= ","; 6159 c_expr.expr &:= stringInComment(stri); 6160 c_expr.expr &:= "\n"; 6161 end for; 6162 else 6163 c_expr.expr &:= "(striType) NULL"; 6164 end if; 6165 c_expr.expr &:= "};\n\n"; 6166 end func; 6167 6168 6169const proc: init_string_constants (inout expr_type: c_expr) is func 6170 6171 local 6172 var stri_index_hash: stri_index is stri_index_hash.EMPTY_HASH; 6173 begin 6174 stri_index := flip(stri_const_table); 6175 if ccConf.ALLOW_STRITYPE_SLICES then 6176 init_string_constants_with_slices(stri_index, c_expr); 6177 else 6178 init_string_constants_no_slices(stri_index, c_expr); 6179 end if; 6180 end func; 6181 6182 6183const proc: write_bstriChars (in string: bstriChars, inout expr_type: c_expr) is func 6184 local 6185 var char: ch is ' '; 6186 var integer: countChars is 0; 6187 begin 6188 if length(bstriChars) <> 0 then 6189 c_expr.expr &:= "static unsigned char bstriChars[/*"; 6190 c_expr.expr &:= str(length(bstriChars)); 6191 c_expr.expr &:= "*/]"; 6192 countChars := 0; 6193 if ccConf.LIMITED_CSTRI_LITERAL_LEN then 6194 c_expr.expr &:= "={"; 6195 c_expr.expr &:= "\n"; 6196 for ch range bstriChars do 6197 c_expr.expr &:= c_literal(ch); 6198 c_expr.expr &:= ","; 6199 incr(countChars); 6200 if countChars = 20 then 6201 c_expr.expr &:= "\n"; 6202 countChars := 0; 6203 end if; 6204 end for; 6205 c_expr.expr &:= "};\n\n"; 6206 else 6207 if length(bstriChars) <> 0 then 6208 c_expr.expr &:= "="; 6209 for countChars range 1 to length(bstriChars) step 40 do 6210 c_expr.expr &:= "\n"; 6211 c_expr.expr &:= c_literal(bstriChars[countChars len 40]); 6212 end for; 6213 end if; 6214 c_expr.expr &:= ";\n\n"; 6215 end if; 6216 end if; 6217 end func; 6218 6219 6220const proc: write_bst_table (in bstri_index_hash: bstri_index, 6221 in array integer: stringPosition, inout expr_type: c_expr) is func 6222 local 6223 var integer: number is 0; 6224 var string: stri is ""; 6225 begin 6226 c_expr.expr &:= "struct bstriStruct bst[]={\n"; 6227 if length(bstri_const_table) > 0 then 6228 for number range 0 to pred(length(bstri_const_table)) do 6229 stri := str(bstri_index[number][1]); 6230 c_expr.expr &:= "/* bst["; 6231 c_expr.expr &:= str(number); 6232 c_expr.expr &:= "] */ {"; 6233 c_expr.expr &:= str(length(stri)); 6234 c_expr.expr &:= ","; 6235 if stri = "" then 6236 c_expr.expr &:= "NULL"; 6237 else 6238 c_expr.expr &:= "&bstriChars["; 6239 c_expr.expr &:= str(pred(stringPosition[number])); 6240 c_expr.expr &:= "]"; 6241 end if; 6242 c_expr.expr &:= "},"; 6243 c_expr.expr &:= stringInComment(stri); 6244 c_expr.expr &:= "\n"; 6245 end for; 6246 else 6247 c_expr.expr &:= "/* dummy */ {0,"; 6248 c_expr.expr &:= "NULL}"; 6249 end if; 6250 c_expr.expr &:= "};\n\n"; 6251 end func; 6252 6253 6254const proc: init_bstri_constants_with_slices (in bstri_index_hash: bstri_index, 6255 inout expr_type: c_expr) is func 6256 6257 local 6258 var stringLengthHash: stringLengths is stringLengthHash.value; 6259 var lengthToStriNumHash: lengthToStriNum is lengthToStriNumHash.value; 6260 var array integer: lengthList is 0 times 0; 6261 var integer: lengthIndex is 0; 6262 var integer: length is 0; 6263 var array integer: stringPosition is 0 times 0; 6264 var integer: number is 0; 6265 var string: stri is ""; 6266 var integer: combinedBStriLength is 0; 6267 var string: bstriChars is ""; 6268 var integer: striPos is 0; 6269 var integer: striIndex is 0; 6270 var boolean: found is FALSE; 6271 begin 6272 stringPosition := [0 .. pred(length(bstri_const_table))] times 0; 6273 for number range 0 to pred(length(bstri_const_table)) do 6274 stringLengths @:= [number] length(bstri_index[number][1]); 6275 end for; 6276 lengthToStriNum := flip(stringLengths); 6277 lengthList := sort(keys(lengthToStriNum)); 6278 for lengthIndex range maxIdx(lengthList) downto minIdx(lengthList) do 6279 length := lengthList[lengthIndex]; 6280 if length in lengthToStriNum then 6281 for number range lengthToStriNum[length] do 6282 stri := str(bstri_index[number][1]); 6283 combinedBStriLength +:= length(stri); 6284 striPos := pos(bstriChars, stri); 6285 if striPos = 0 then 6286 found := FALSE; 6287 if length(bstriChars) > length(stri) then 6288 striIndex := rpos(stri, bstriChars[length(bstriChars)]); 6289 while striIndex <> 0 and not found do 6290 if stri[.. striIndex] = bstriChars[succ(length(bstriChars) - striIndex) ..] then 6291 stringPosition[number] := succ(length(bstriChars) - striIndex); 6292 bstriChars &:= stri[succ(striIndex) ..]; 6293 found := TRUE; 6294 else 6295 striIndex := rpos(stri, bstriChars[length(bstriChars)], pred(striIndex)); 6296 end if; 6297 end while; 6298 end if; 6299 if not found then 6300 stringPosition[number] := succ(length(bstriChars)); 6301 bstriChars &:= stri; 6302 end if; 6303 else 6304 stringPosition[number] := striPos; 6305 end if; 6306 end for; 6307 end if; 6308 end for; 6309 write_bstriChars(bstriChars, c_expr); 6310 write_bst_table(bstri_index, stringPosition, c_expr); 6311 if SHOW_STATISTIC then 6312 writeln(combinedBStriLength <& " chars in all bstrings"); 6313 writeln(length(bstriChars) <& " chars in bstring pool"); 6314 writeln(combinedBStriLength - length(bstriChars) <& " chars of bstring memory saved"); 6315 end if; 6316 end func; 6317 6318 6319const proc: init_bstri_constants_no_slices (in bstri_index_hash: bstri_index, 6320 inout expr_type: c_expr) is func 6321 6322 local 6323 var bstring: bstri is bstring.value; 6324 var integer: number is 0; 6325 var string: lengthAsChars is ""; 6326 var string: stri is ""; 6327 var integer: countChars is 0; 6328 var char: ch is ' '; 6329 begin 6330 for number range sort(keys(bstri_index)) do 6331 bstri := bstri_index[number][1]; 6332 c_expr.expr &:= "/* bst["; 6333 c_expr.expr &:= str(number); 6334 c_expr.expr &:= "] */ static const unsigned char bstri_"; 6335 c_expr.expr &:= str(number); 6336 if ccConf.POINTER_SIZE = 32 then 6337 lengthAsChars := int32AsFourBytes(length(bstri)); 6338 elsif ccConf.POINTER_SIZE = 64 then 6339 lengthAsChars := int64AsEightBytes(length(bstri)); 6340 end if; 6341 countChars := 0; 6342 if ccConf.LIMITED_CSTRI_LITERAL_LEN then 6343 c_expr.expr &:= "[]={"; 6344 for ch range lengthAsChars do 6345 c_expr.expr &:= c_literal(ch); 6346 c_expr.expr &:= ","; 6347 end for; 6348 c_expr.expr &:= "\n"; 6349 for ch range bstri do 6350 c_expr.expr &:= c_literal(ch); 6351 c_expr.expr &:= ","; 6352 incr(countChars); 6353 if countChars = 20 then 6354 c_expr.expr &:= "\n"; 6355 countChars := 0; 6356 end if; 6357 end for; 6358 c_expr.expr &:= "};\n"; 6359 else 6360 c_expr.expr &:= "[]="; 6361 c_expr.expr &:= c_literal(lengthAsChars); 6362 if length(bstri) <> 0 then 6363 stri := str(bstri); 6364 for countChars range 1 to length(stri) step 40 do 6365 c_expr.expr &:= "\n"; 6366 c_expr.expr &:= c_literal(stri[countChars len 40]); 6367 end for; 6368 end if; 6369 c_expr.expr &:= ";\n"; 6370 end if; 6371 end for; 6372 c_expr.expr &:= "bstriType bst[]={\n"; 6373 if length(bstri_const_table) > 0 then 6374 for number range sort(keys(bstri_index)) do 6375 c_expr.expr &:= "(bstriType) bstri_"; 6376 c_expr.expr &:= str(number); 6377 c_expr.expr &:= ",\n"; 6378 end for; 6379 else 6380 c_expr.expr &:= "(bstriType) NULL"; 6381 end if; 6382 c_expr.expr &:= "};\n\n"; 6383 end func; 6384 6385 6386const proc: init_bstri_constants (inout expr_type: c_expr) is func 6387 6388 local 6389 var bstri_index_hash: bstri_index is bstri_index_hash.EMPTY_HASH; 6390 begin 6391 bstri_index := flip(bstri_const_table); 6392 if ccConf.ALLOW_BSTRITYPE_SLICES then 6393 init_bstri_constants_with_slices(bstri_index, c_expr); 6394 else 6395 init_bstri_constants_no_slices(bstri_index, c_expr); 6396 end if; 6397 end func; 6398 6399 6400const proc: init_set_constants (inout expr_type: c_expr) is func 6401 6402 local 6403 var set_index_hash: set_index is set_index_hash.EMPTY_HASH; 6404 var bitset: set1 is EMPTY_SET; 6405 var integer: min_position is 0; 6406 var integer: max_position is 0; 6407 var integer: number is 0; 6408 var integer: elem_num is 0; 6409 var integer: columnsFree is 0; 6410 begin 6411 set_index := flip(set_const_table); 6412 for number range sort(keys(set_index)) do 6413 set1 := set_index[number][1]; 6414 c_expr.expr &:= "/* set["; 6415 c_expr.expr &:= str(number); 6416 c_expr.expr &:= "] */ static bitSetType set_"; 6417 c_expr.expr &:= str(number); 6418 c_expr.expr &:= "[]={"; 6419 if set1 = EMPTY_SET then 6420 c_expr.expr &:= "0,0,0,"; 6421 else 6422 min_position := min(set1) mdiv ccConf.INTTYPE_SIZE; 6423 max_position := max(set1) mdiv ccConf.INTTYPE_SIZE; 6424 if min_position < 0 then 6425 c_expr.expr &:= "(bitSetType)"; 6426 end if; 6427 c_expr.expr &:= str(min_position); 6428 c_expr.expr &:= ","; 6429 if max_position < 0 then 6430 c_expr.expr &:= "(bitSetType)"; 6431 end if; 6432 c_expr.expr &:= str(max_position); 6433 c_expr.expr &:= ","; 6434 columnsFree := 4; 6435 for elem_num range min_position to max_position do 6436 if columnsFree = 0 then 6437 c_expr.expr &:= "\n"; 6438 columnsFree := 6; 6439 end if; 6440 c_expr.expr &:= "0x"; 6441 c_expr.expr &:= getBinary(set1, elem_num * ccConf.INTTYPE_SIZE) radix 16 lpad0 16; 6442 c_expr.expr &:= ","; 6443 decr(columnsFree); 6444 end for; 6445 end if; 6446 c_expr.expr &:= "};\n"; 6447 end for; 6448 c_expr.expr &:= "setType set[]={\n"; 6449 if length(set_const_table) > 0 then 6450 for number range sort(keys(set_index)) do 6451 c_expr.expr &:= "(setType) set_"; 6452 c_expr.expr &:= str(number); 6453 c_expr.expr &:= ",\n"; 6454 end for; 6455 else 6456 c_expr.expr &:= "(setType) NULL"; 6457 end if; 6458 c_expr.expr &:= "};\n\n"; 6459 end func; 6460 6461 6462const proc: init_type_constants (inout expr_type: c_expr) is func 6463 6464 local 6465 var type_index_hash: type_index is type_index_hash.EMPTY_HASH; 6466 var type: aType is void; 6467 var integer: number is 0; 6468 begin 6469 type_index := flip(type_const_table); 6470 for number range sort(keys(type_index)) do 6471 aType := type_index[number][1]; 6472 c_expr.expr &:= "/* typ["; 6473 c_expr.expr &:= str(number); 6474 c_expr.expr &:= "] */ static struct typeStruct typ_"; 6475 c_expr.expr &:= str(number); 6476 c_expr.expr &:= "={"; 6477 c_expr.expr &:= "NULL, NULL, NULL, NULL, NULL, 0, NULL, NULL"; 6478 # c_expr.expr &:= c_literal(aType); 6479 c_expr.expr &:= "};\n"; 6480 end for; 6481 c_expr.expr &:= "typeType typ[]={\n"; 6482 if length(type_const_table) > 0 then 6483 for number range sort(keys(type_index)) do 6484 aType := type_index[number][1]; 6485 c_expr.expr &:= "&typ_"; 6486 c_expr.expr &:= str(number); 6487 c_expr.expr &:= ", /* "; 6488 c_expr.expr &:= type_name2(aType); 6489 c_expr.expr &:= " */\n"; 6490 end for; 6491 else 6492 c_expr.expr &:= "(typeType) NULL"; 6493 end if; 6494 c_expr.expr &:= "};\n\n"; 6495 end func; 6496 6497 6498const proc: init_array_constants (in reference: const_object, inout expr_type: c_expr) is func 6499 6500 local 6501 var ref_list: array_list is ref_list.EMPTY; 6502 var integer: number is 0; 6503 var integer: elem_num is 0; 6504 var integer: elem_after_repeat_block is 0; 6505 var reference: element is NIL; 6506 begin 6507 number := const_table[const_object]; 6508 array_list := arrayToList(const_object); 6509 c_expr.expr &:= "arr["; 6510 c_expr.expr &:= str(number); 6511 c_expr.expr &:= "]=arrMalloc("; 6512 c_expr.expr &:= str(arrayMinIdx(const_object)); 6513 c_expr.expr &:= ", "; 6514 c_expr.expr &:= str(pred(arrayMinIdx(const_object) + length(array_list))); 6515 c_expr.expr &:= ");\n"; 6516 elem_num := 0; 6517 elem_after_repeat_block := 0; 6518 for element range array_list do 6519 if element in element_repeat_count then 6520 c_expr.expr &:= "{\n"; 6521 c_expr.expr &:= "int idx;\n"; 6522 c_expr.expr &:= "for (idx="; 6523 c_expr.expr &:= str(elem_num); 6524 c_expr.expr &:= "; idx < "; 6525 c_expr.expr &:= str(elem_num + element_repeat_count[element]); 6526 c_expr.expr &:= "; idx++) {\n"; 6527 c_expr.expr &:= "arr["; 6528 c_expr.expr &:= str(number); 6529 c_expr.expr &:= "]->arr[idx]"; 6530 init_const_value(element, c_expr); 6531 c_expr.expr &:= ";\n"; 6532 c_expr.expr &:= "}\n"; 6533 c_expr.expr &:= "}\n"; 6534 elem_after_repeat_block := elem_num + element_repeat_count[element]; 6535 elsif elem_num >= elem_after_repeat_block then 6536 c_expr.expr &:= "arr["; 6537 c_expr.expr &:= str(number); 6538 c_expr.expr &:= "]->arr["; 6539 c_expr.expr &:= str(elem_num); 6540 c_expr.expr &:= "]"; 6541 init_const_value(element, c_expr); 6542 c_expr.expr &:= ";\n"; 6543 end if; 6544 incr(elem_num); 6545 end for; 6546 end func; 6547 6548 6549const proc: malloc_struct (in reference: const_object, inout expr_type: c_expr) is func 6550 6551 local 6552 var ref_list: struct_list is ref_list.EMPTY; 6553 var integer: number is 0; 6554 var integer: elem_num is 0; 6555 var reference: element is NIL; 6556 begin 6557 number := const_table[const_object]; 6558 struct_list := structToList(const_object); 6559 c_expr.expr &:= "sct["; 6560 c_expr.expr &:= str(number); 6561 c_expr.expr &:= "]=(structType)(malloc(sizeof(struct rtlStructStruct) - sizeof(rtlObjectType)"; 6562 if length(struct_list) <> 0 then 6563 c_expr.expr &:= " +\n "; 6564 c_expr.expr &:= str(length(struct_list)); 6565 c_expr.expr &:= " * sizeof(rtlObjectType)"; 6566 end if; 6567 c_expr.expr &:= "));\n"; 6568 end func; 6569 6570 6571const proc: init_struct_constants (in reference: const_object, inout expr_type: c_expr) is func 6572 6573 local 6574 var ref_list: struct_list is ref_list.EMPTY; 6575 var integer: number is 0; 6576 var integer: elem_num is 0; 6577 var reference: element is NIL; 6578 begin 6579 number := const_table[const_object]; 6580 struct_list := structToList(const_object); 6581 c_expr.expr &:= "sct["; 6582 c_expr.expr &:= str(number); 6583 c_expr.expr &:= "]->usage_count=0;\n"; 6584 c_expr.expr &:= "sct["; 6585 c_expr.expr &:= str(number); 6586 c_expr.expr &:= "]->type_num="; 6587 c_expr.expr &:= str(typeNumber(getType(const_object))); 6588 c_expr.expr &:= "/*"; 6589 c_expr.expr &:= str(getType(const_object)); 6590 c_expr.expr &:= "*/"; 6591 c_expr.expr &:= ";\n"; 6592 elem_num := 1; 6593 for element range struct_list do 6594 c_expr.expr &:= "sct["; 6595 c_expr.expr &:= str(number); 6596 c_expr.expr &:= "]->stru["; 6597 c_expr.expr &:= str(pred(elem_num)); 6598 c_expr.expr &:= "]"; 6599 init_const_value(element, c_expr); 6600 c_expr.expr &:= ";\n"; 6601 incr(elem_num); 6602 end for; 6603 if const_object in globalInitalisations then 6604 c_expr.expr &:= globalInitalisations[const_object]; 6605 end if; 6606 end func; 6607 6608 6609const proc: init_hash_constants (in reference: const_object, inout expr_type: c_expr) is func 6610 6611 local 6612 var ref_list: hash_key_list is ref_list.EMPTY; 6613 var ref_list: hash_data_list is ref_list.EMPTY; 6614 var integer: number is 0; 6615 var integer: elem_num is 0; 6616 var reference: key_element is NIL; 6617 var expr_type: hashcode_expr is expr_type.value; 6618 begin 6619 number := const_table[const_object]; 6620 hash_key_list := hashKeysToList(const_object); 6621 hash_data_list := hashDataToList(const_object); 6622 c_expr.expr &:= "hsh["; 6623 c_expr.expr &:= str(number); 6624 c_expr.expr &:= "]=hshEmpty();\n"; 6625 if length(hash_key_list) <> 0 then 6626 c_expr.expr &:= "{\n"; 6627 c_expr.expr &:= "rtlObjectType hash_key;\n"; 6628 c_expr.expr &:= "rtlObjectType hash_data;\n"; 6629 elem_num := 1; 6630 for key_element range hash_key_list do 6631 c_expr.expr &:= "hash_key"; 6632 init_const_value(key_element, c_expr); 6633 c_expr.expr &:= ";\n"; 6634 c_expr.expr &:= "hash_data"; 6635 init_const_value(hash_data_list[elem_num], c_expr); 6636 c_expr.expr &:= ";\n"; 6637 hashcode_expr := expr_type.value; 6638 setVar(key_element, FALSE); 6639 process_hashcode(key_element, hashcode_expr); 6640 if hashcode_expr.temp_decls <> "" then 6641 c_expr.expr &:= "{\n"; 6642 c_expr.expr &:= hashcode_expr.temp_decls; 6643 c_expr.expr &:= hashcode_expr.temp_assigns; 6644 end if; 6645 c_expr.expr &:= "hshIncl(hsh["; 6646 c_expr.expr &:= str(number); 6647 c_expr.expr &:= "], hash_key.value.genericValue, hash_data.value.genericValue, "; 6648 c_expr.expr &:= hashcode_expr.expr; 6649 c_expr.expr &:= ", (compareType)("; 6650 object_address(keyCompareObj(getType(const_object)), c_expr); 6651 c_expr.expr &:= "), (createFuncType)("; 6652 object_address(keyCreateObj(getType(const_object)), c_expr); 6653 c_expr.expr &:= "), (createFuncType)("; 6654 object_address(dataCreateObj(getType(const_object)), c_expr); 6655 c_expr.expr &:= "), (copyFuncType)("; 6656 object_address(dataCopyObj(getType(const_object)), c_expr); 6657 c_expr.expr &:= "));\n"; 6658 if hashcode_expr.temp_decls <> "" then 6659 c_expr.expr &:= hashcode_expr.temp_frees; 6660 c_expr.expr &:= "}\n"; 6661 end if; 6662 incr(elem_num); 6663 end for; 6664 c_expr.expr &:= "}\n"; 6665 end if; 6666 end func; 6667 6668 6669const proc: init_interface_constants (in reference: const_object, inout expr_type: c_expr) is func 6670 6671 local 6672 var reference: struct_of_interface is NIL; 6673 var integer: number is 0; 6674 begin 6675 number := const_table[const_object]; 6676 struct_of_interface := interfaceToStruct(const_object); 6677 c_expr.expr &:= "itf["; 6678 c_expr.expr &:= str(number); 6679 c_expr.expr &:= "]"; 6680 if isVar(struct_of_interface) and struct_of_interface in globalInitalisations then 6681 c_expr.expr &:= "=o_"; 6682 create_name(struct_of_interface, c_expr.expr); 6683 elsif category(struct_of_interface) = STRUCTOBJECT then 6684 c_expr.expr &:= "=sct["; 6685 c_expr.expr &:= str(const_table[struct_of_interface]); 6686 c_expr.expr &:= "]"; 6687 else 6688 c_expr.expr &:= " /* = "; 6689 c_expr.expr &:= str(category(struct_of_interface)); 6690 c_expr.expr &:= " */"; 6691 end if; 6692 c_expr.expr &:= ";\n"; 6693 end func; 6694 6695 6696const proc: init_nan_constants (inout expr_type: c_expr) is func 6697 6698 local 6699 var nan_index_hash: nan_index is nan_index_hash.EMPTY_HASH; 6700 var integer: number is 0; 6701 var bin64: bits is bin64(0); 6702 begin 6703 c_expr.expr &:= "double2BitsUnion nanValue[] = {\n"; 6704 if length(nan_const_table) > 0 then 6705 nan_index := flip(nan_const_table); 6706 for number range sort(keys(nan_index)) do 6707 bits := nan_index[number][1]; 6708 c_expr.expr &:= "{0x"; 6709 c_expr.expr &:= bits radix 16 lpad0 16; 6710 c_expr.expr &:= "},\n"; 6711 end for; 6712 else 6713 c_expr.expr &:= "{0}"; 6714 end if; 6715 c_expr.expr &:= "};\n\n"; 6716 end func; 6717 6718 6719const proc: initCaseLabelsOfWhen (in integer: numOfCaseStmt, in integer: numOfWhenPart, 6720 in reference: whenLabels, inout expr_type: c_expr) is func 6721 6722 local 6723 var ref_list: hash_key_list is ref_list.EMPTY; 6724 var reference: key_element is NIL; 6725 var expr_type: hashcode_expr is expr_type.value; 6726 begin 6727 hash_key_list := hashKeysToList(whenLabels); 6728 if length(hash_key_list) <> 0 then 6729 for key_element range hash_key_list do 6730 c_expr.expr &:= "hash_key"; 6731 init_const_value(key_element, c_expr); 6732 c_expr.expr &:= ";\n"; 6733 hashcode_expr := expr_type.value; 6734 setVar(key_element, FALSE); 6735 process_hashcode(key_element, hashcode_expr); 6736 if hashcode_expr.temp_decls <> "" then 6737 c_expr.expr &:= "{\n"; 6738 c_expr.expr &:= hashcode_expr.temp_decls; 6739 c_expr.expr &:= hashcode_expr.temp_assigns; 6740 end if; 6741 c_expr.expr &:= "hshIncl(caseLabels["; 6742 c_expr.expr &:= str(numOfCaseStmt); 6743 c_expr.expr &:= "], hash_key.value.genericValue, "; 6744 c_expr.expr &:= str(numOfWhenPart); 6745 c_expr.expr &:= ", "; 6746 c_expr.expr &:= hashcode_expr.expr; 6747 c_expr.expr &:= ", (compareType)("; 6748 object_address(keyCompareObj(getType(whenLabels)), c_expr); 6749 c_expr.expr &:= "), (createFuncType)("; 6750 object_address(keyCreateObj(getType(whenLabels)), c_expr); 6751 c_expr.expr &:= "), (createFuncType)(&genericCreate), (copyFuncType)(&genericCpy));\n"; 6752 if hashcode_expr.temp_decls <> "" then 6753 c_expr.expr &:= hashcode_expr.temp_frees; 6754 c_expr.expr &:= "}\n"; 6755 end if; 6756 end for; 6757 end if; 6758 end func; 6759 6760 6761const proc: initCaseLabelsOfCase (in integer: numOfCaseStmt, 6762 in array reference: caseWhens, inout expr_type: c_expr) is func 6763 6764 local 6765 var integer: numOfWhenPart is 0; 6766 var reference: whenLabels is NIL; 6767 begin 6768 c_expr.expr &:= "caseLabels["; 6769 c_expr.expr &:= str(numOfCaseStmt); 6770 c_expr.expr &:= "]=hshEmpty();\n"; 6771 for whenLabels key numOfWhenPart range caseWhens do 6772 initCaseLabelsOfWhen(numOfCaseStmt, numOfWhenPart, whenLabels, c_expr); 6773 end for; 6774 end func; 6775 6776 6777const proc: initCaseLabels (inout expr_type: c_expr) is func 6778 6779 local 6780 var integer: numOfCaseStmt is 0; 6781 begin 6782 c_expr.expr &:= "void initCaseLabelsOfSwitch () {\n"; 6783 if length(case_table) <> 0 then 6784 c_expr.expr &:= "rtlObjectType hash_key;\n"; 6785 c_expr.expr &:= "caseLabels = (hashType *)(malloc("; 6786 c_expr.expr &:= str(length(case_table)); 6787 c_expr.expr &:= " * sizeof(hashType)));\n"; 6788 for key numOfCaseStmt range case_table do 6789 initCaseLabelsOfCase(numOfCaseStmt, case_table[numOfCaseStmt], c_expr); 6790 end for; 6791 end if; 6792 c_expr.expr &:= "}\n\n"; 6793 end func; 6794 6795 6796const proc: init_values (inout expr_type: c_expr) is func 6797 6798 local 6799 var const_index_hash: const_index is const_index_hash.EMPTY_HASH; 6800 var ref_list: sorted_list is ref_list.EMPTY; 6801 var reference: struct_of_interface is NIL; 6802 var reference: const_object is NIL; 6803 var integer: number is 0; 6804 var ref_list: elements_to_walk is ref_list.EMPTY; 6805 begin 6806 const_index := flip(const_table); 6807 for number range sort(keys(const_index)) do 6808 const_object := const_index[number][1]; 6809 if category(const_object) = ARRAYOBJECT then 6810 elements_to_walk := determine_multiple_array_elements(arrayToList(const_object)); 6811 walk_const_list(elements_to_walk, sorted_list); 6812 sorted_list &:= make_list(const_object); 6813 elsif category(const_object) = STRUCTOBJECT then 6814 walk_const_list(structToList(const_object), sorted_list); 6815 sorted_list &:= make_list(const_object); 6816 elsif category(const_object) = HASHOBJECT then 6817 walk_const_list(hashKeysToList(const_object), sorted_list); 6818 walk_const_list(hashDataToList(const_object), sorted_list); 6819 sorted_list &:= make_list(const_object); 6820 elsif category(const_object) = INTERFACEOBJECT then 6821 if const_object not in const_table then 6822 const_table @:= [const_object] length(const_table); 6823 end if; 6824 struct_of_interface := interfaceToStruct(const_object); 6825 if struct_of_interface not in const_table then 6826 const_table @:= [struct_of_interface] length(const_table); 6827 walk_const_list(structToList(struct_of_interface), sorted_list); 6828 sorted_list &:= make_list(struct_of_interface); 6829 elsif const_table[struct_of_interface] >= const_table[const_object] then 6830 sorted_list &:= make_list(struct_of_interface); 6831 end if; 6832 sorted_list &:= make_list(const_object); 6833 end if; 6834 end for; 6835 writeln("after walk_const_list"); 6836 6837 for const_object range sorted_list do 6838 # writeln(str(category(const_object)) <& ": " <& create_name(const_object)); 6839 if category(const_object) = MATCHOBJECT or category(const_object) = ACTOBJECT or 6840 category(const_object) = BLOCKOBJECT then 6841 prepare_func_literal(const_object, c_expr); 6842 end if; 6843 end for; 6844 6845 init_bigint_constants; 6846 init_win_constants; 6847 init_string_constants(c_expr); 6848 init_bstri_constants(c_expr); 6849 init_set_constants(c_expr); 6850 init_type_constants(c_expr); 6851 6852 c_expr.expr &:= "static void init_values (void)\n"; 6853 c_expr.expr &:= "{\n"; 6854 initPollOperations(c_expr); 6855 assign_bigint_constants(c_expr); 6856 assign_win_constants(c_expr); 6857 c_expr.expr &:= "arr = (arrayType *)(malloc("; 6858 c_expr.expr &:= str(length(const_table)); 6859 c_expr.expr &:= " * sizeof(arrayType)));\n"; 6860 c_expr.expr &:= "sct = (structType *)(arr);\n"; 6861 c_expr.expr &:= "hsh = (hashType *)(arr);\n"; 6862 c_expr.expr &:= "itf = (interfaceType *)(arr);\n"; 6863 for const_object range sorted_list do 6864 if category(const_object) = STRUCTOBJECT then 6865 malloc_struct(const_object, c_expr); 6866 end if; 6867 end for; 6868 for const_object range sorted_list do 6869 if category(const_object) = ARRAYOBJECT then 6870 init_array_constants(const_object, c_expr); 6871 elsif category(const_object) = STRUCTOBJECT then 6872 init_struct_constants(const_object, c_expr); 6873 elsif category(const_object) = HASHOBJECT then 6874 init_hash_constants(const_object, c_expr); 6875 elsif category(const_object) = INTERFACEOBJECT then 6876 init_interface_constants(const_object, c_expr); 6877 elsif category(const_object) <> MATCHOBJECT and 6878 category(const_object) <> ACTOBJECT then 6879 number := const_table[const_object]; 6880 c_expr.expr &:= "/* const "; 6881 c_expr.expr &:= str(category(const_object)); 6882 c_expr.expr &:= " ["; 6883 c_expr.expr &:= str(number); 6884 c_expr.expr &:= "] */\n"; 6885 end if; 6886 end for; 6887 c_expr.expr &:= "initCaseLabelsOfSwitch();\n"; 6888 c_expr.expr &:= "}\n\n"; 6889 init_nan_constants(c_expr); 6890 end func; 6891 6892 6893const proc: declare_rtlRaiseError (inout expr_type: c_expr) is func 6894 6895 begin 6896 c_expr.expr &:= "void rtlRaiseError (int fail_value, const char *file_name, int line_number)\n"; 6897 c_expr.expr &:= "{\n"; 6898 if trace_exception then 6899 c_expr.expr &:= " int ch;\n"; 6900 c_expr.expr &:= " if (catch_stack_pos == 0) {\n"; 6901 c_expr.expr &:= " printf(\"\\n*** Uncaught exception \");\n"; 6902 c_expr.expr &:= " } else {\n"; 6903 c_expr.expr &:= " printf(\"\\n*** Caught exception \");\n"; 6904 c_expr.expr &:= " }\n"; 6905 c_expr.expr &:= " if (fail_value >= 0 && fail_value < sizeof(exception_name) / sizeof(char *)) {\n"; 6906 c_expr.expr &:= " printf(\"%s\", exception_name[fail_value]);\n"; 6907 c_expr.expr &:= " } else {\n"; 6908 c_expr.expr &:= " printf(\"%d\", fail_value);\n"; 6909 c_expr.expr &:= " }\n"; 6910 c_expr.expr &:= " printf(\" raised at %s(%d)\\n\", file_name, line_number);\n"; 6911 c_expr.expr &:= " printf(\"\\n*** The following commands are possible:\\n\"\n"; 6912 c_expr.expr &:= " \" RETURN Continue\\n\"\n"; 6913 c_expr.expr &:= " \" * Terminate\\n\"\n"; 6914 c_expr.expr &:= " \" / Trigger SIGFPE\\n\");\n"; 6915 c_expr.expr &:= " ch = fgetc(stdin);\n"; 6916 c_expr.expr &:= " if (ch == (int) '*') {\n"; 6917 c_expr.expr &:= " exit(1);\n"; 6918 c_expr.expr &:= " } else if (ch == (int) '/') {\n"; 6919 c_expr.expr &:= " triggerSigfpe();\n"; 6920 c_expr.expr &:= " }\n"; 6921 end if; 6922 c_expr.expr &:= " error_file = file_name;\n"; 6923 c_expr.expr &:= " error_line = line_number;\n"; 6924 if signal_exception then 6925 c_expr.expr &:= " if (catch_stack_pos == 0) {\n"; 6926 c_expr.expr &:= " printf(\"\\n*** Uncaught exception \");\n"; 6927 c_expr.expr &:= " if (fail_value >= 0 && fail_value < sizeof(exception_name) / sizeof(char *)) {\n"; 6928 c_expr.expr &:= " printf(\"%s\", exception_name[fail_value]);\n"; 6929 c_expr.expr &:= " } else {\n"; 6930 c_expr.expr &:= " printf(\"%d\", fail_value);\n"; 6931 c_expr.expr &:= " }\n"; 6932 c_expr.expr &:= " printf(\" raised at %s(%d)\\n\", file_name, line_number);\n"; 6933 c_expr.expr &:= " triggerSigfpe();\n"; 6934 c_expr.expr &:= " }\n"; 6935 end if; 6936 if ccConf.HAS_SIGSETJMP then 6937 c_expr.expr &:= " siglongjmp(catch_stack[catch_stack_pos], fail_value);\n"; 6938 else 6939 c_expr.expr &:= " longjmp(catch_stack[catch_stack_pos], fail_value);\n"; 6940 end if; 6941 c_expr.expr &:= "}\n"; 6942 c_expr.expr &:= "\n"; 6943 end func; 6944 6945 6946const proc: declare_raise_error2 (inout expr_type: c_expr) is func 6947 6948 begin 6949 if compilerLibraryUsed then 6950 writeln(c_prog, "extern boolType interpreter_exception;"); 6951 declareExtern("void interprRaiseError (int, const char *, int);"); 6952 end if; 6953 c_expr.expr &:= "void raise_error2 (int fail_value, const char *file_name, int line_number)\n"; 6954 c_expr.expr &:= "{\n"; 6955 if compilerLibraryUsed then 6956 c_expr.expr &:= " if (interpreter_exception) {\n"; 6957 if trace_exception then 6958 c_expr.expr &:= " int ch;\n"; 6959 c_expr.expr &:= " if (fail_value >= 0 && fail_value < sizeof(exception_name) / sizeof(char *)) {\n"; 6960 c_expr.expr &:= " printf(\"*** Exception %s\", exception_name[fail_value]);\n"; 6961 c_expr.expr &:= " } else {\n"; 6962 c_expr.expr &:= " printf(\"*** Exception %d\", fail_value);\n"; 6963 c_expr.expr &:= " }\n"; 6964 c_expr.expr &:= " printf(\" raised at %s(%d)\\n\", file_name, line_number);\n"; 6965 c_expr.expr &:= " printf(\"\\n*** The following commands are possible:\\n\"\n"; 6966 c_expr.expr &:= " \" RETURN Continue\\n\"\n"; 6967 c_expr.expr &:= " \" * Terminate\\n\"\n"; 6968 c_expr.expr &:= " \" / Trigger SIGFPE\\n\");\n"; 6969 c_expr.expr &:= " ch = fgetc(stdin);\n"; 6970 c_expr.expr &:= " if (ch == (int) '*') {\n"; 6971 c_expr.expr &:= " exit(1);\n"; 6972 c_expr.expr &:= " } else if (ch == (int) '/') {\n"; 6973 c_expr.expr &:= " triggerSigfpe();\n"; 6974 c_expr.expr &:= " }\n"; 6975 end if; 6976 c_expr.expr &:= " interprRaiseError(fail_value, file_name, line_number);\n"; 6977 c_expr.expr &:= " } else {\n"; 6978 c_expr.expr &:= " rtlRaiseError(fail_value, file_name, line_number);\n"; 6979 c_expr.expr &:= " }\n"; 6980 else 6981 c_expr.expr &:= " rtlRaiseError(fail_value, file_name, line_number);\n"; 6982 end if; 6983 c_expr.expr &:= "}\n"; 6984 c_expr.expr &:= "\n"; 6985 end func; 6986 6987 6988const proc: init_globals (inout expr_type: c_expr) is func 6989 6990 begin 6991 c_expr.expr &:= "static void init_globals (void)\n"; 6992 c_expr.expr &:= "{\n"; 6993 c_expr.expr &:= global_init.temp_decls; 6994 c_expr.expr &:= global_init.temp_assigns; 6995 c_expr.expr &:= global_init.expr; 6996 c_expr.expr &:= "}\n\n"; 6997 end func; 6998 6999 7000const proc: process_global_declarations (in program: prog) is func 7001 7002 local 7003 var expr_type: c_expr is expr_type.value; 7004 var type: int_type is void; 7005 var integer: numObjects is 0; 7006 var integer: index is 0; 7007 begin 7008 if not compDataLibraryUsed then 7009 declareExtern("intType heapsize (void) {return 0;}"); 7010 declareExtern("typeType refType (objRefType a) {printf(\"refType\\n\"); return NULL;}"); 7011 declareExtern("typeType typValue (objRefType a) {printf(\"typValue\\n\"); return NULL;}"); 7012 writeln(c_prog); 7013 end if; 7014 if compDataLibraryUsed and not compilerLibraryUsed then 7015 declareExtern("striType get_file_name (unsigned int a) {return " <& stringLiteral("") <& ";}"); 7016 declareExtern("const unsigned char *get_file_name_ustri (unsigned int a) {return (unsigned char *) \"?\";}"); 7017 declareExtern("void *get_param_list (const_listType a, int *b) {printf(\"get_param_list\\n\"); return NULL;}"); 7018 writeln(c_prog); 7019 end if; 7020 declare_rtlRaiseError(c_expr); 7021 declare_raise_error2(c_expr); 7022 process_dynamic_decisions(c_expr); 7023 declare_missing_create_declarations(c_expr); 7024 declare_missing_destr_declarations(c_expr); 7025 initCaseLabels(c_expr); 7026 init_values(c_expr); 7027 init_globals(c_expr); 7028 if profile_function then 7029 int_type := getValue(sysVar(prog, "integer"), type); 7030 numObjects := objNumber(alloc(TRUE, int_type, 0)); 7031 writeln(c_prog, "static unsigned int profile_size = " <& numObjects <& ";"); 7032 writeln(c_prog, "static struct profileElement profile[" <& numObjects <& "];"); 7033 writeln(c_prog); 7034 writeln(c_prog, "static void initProfile (void)"); 7035 writeln(c_prog, "{"); 7036 writeln(c_prog, " memSizeType index;"); 7037 writeln(c_prog, " memset(profile, 0, " <& numObjects <& " * sizeof(struct profileElement));"); 7038 writeln(c_prog, " for (index = 0; index < " <& numObjects <& "; index++) {"); 7039 writeln(c_prog, " profile[index].file = \"\";"); 7040 writeln(c_prog, " profile[index].name = \"\";"); 7041 writeln(c_prog, " }"); 7042 for index range 1 to pred(numObjects) do 7043 if index in profiledFunctions then 7044 write(c_prog, " profile[" <& index <& "].file = " <& 7045 c_literal(striToUtf8(file(profiledFunctions[index]))) <& ";"); 7046 write(c_prog, " profile[" <& index <& "].line = " <& 7047 line(profiledFunctions[index]) <& ";"); 7048 writeln(c_prog, " profile[" <& index <& "].name = " <& 7049 c_literal(striToUtf8(str(profiledFunctions[index]))) <& ";"); 7050 end if; 7051 end for; 7052 writeln(c_prog, "}"); 7053 writeln(c_prog); 7054 end if; 7055 write(c_prog, global_c_expr.expr); 7056 write(c_prog, c_expr.expr); 7057 count_declarations(c_expr); 7058 end func; 7059 7060 7061const proc: init_systypes (in program: prog) is func 7062 7063 local 7064 var reference: type_ref is NIL; 7065 var reference: ref_to_empty is NIL; 7066 var type: type_type is void; 7067 var type: int_type is void; 7068 var type: float_type is void; 7069 var type: bigint_type is void; 7070 var type: char_type is void; 7071 var type: stri_type is void; 7072 begin 7073 type_ref := sysVar(prog, "type"); 7074 if type_ref <> NIL then 7075 type_type := getValue(type_ref, type); 7076 typeCategory @:= [type_type] TYPEOBJECT; 7077 end if; 7078 type_ref := sysVar(prog, "proc"); 7079 if type_ref <> NIL then 7080 proctype := getValue(type_ref, type); 7081 end if; 7082 type_ref := sysVar(prog, "integer"); 7083 if type_ref <> NIL then 7084 int_type := getValue(type_ref, type); 7085 typeCategory @:= [int_type] INTOBJECT; 7086 end if; 7087 type_ref := sysVar(prog, "bigInteger"); 7088 if type_ref <> NIL then 7089 bigint_type := getValue(type_ref, type); 7090 typeCategory @:= [bigint_type] BIGINTOBJECT; 7091 end if; 7092 type_ref := sysVar(prog, "float"); 7093 if type_ref <> NIL then 7094 float_type := getValue(type_ref, type); 7095 typeCategory @:= [float_type] FLOATOBJECT; 7096 end if; 7097 type_ref := sysVar(prog, "char"); 7098 if type_ref <> NIL then 7099 char_type := getValue(type_ref, type); 7100 typeCategory @:= [char_type] CHAROBJECT; 7101 end if; 7102 type_ref := sysVar(prog, "string"); 7103 if type_ref <> NIL then 7104 stri_type := getValue(type_ref, type); 7105 typeCategory @:= [stri_type] STRIOBJECT; 7106 end if; 7107 ref_to_empty := sysVar(prog, "empty"); 7108 if ref_to_empty <> NIL then 7109 voidtype := getType(ref_to_empty); 7110 typeCategory @:= [voidtype] VOIDOBJECT; 7111 end if; 7112 end func; 7113 7114 7115const func string: temp_name (in string: source) is func 7116 result 7117 var string: tempName is ""; 7118 begin 7119 if rpos(source, "/") = 0 then 7120 tempName := "tmp_" & source; 7121 else 7122 tempName := source[.. rpos(source, "/")] & 7123 "tmp_" & source[succ(rpos(source, "/")) ..]; 7124 end if; 7125 end func; 7126 7127 7128const proc: pass_1 (in string: source, inout program: prog, 7129 inout boolean: okay) is func 7130 7131 begin 7132 if source <> "" then 7133 writeln("Compiling the program ..."); 7134 if "-g" in compiler_option then 7135 source_debug_info := compiler_option["-g"] <> "-debug_c"; 7136 end if; 7137 if "-t" in compiler_option then 7138 if pos(compiler_option["-t"], 'e') <> 0 then 7139 trace_exception := TRUE; 7140 end if; 7141 if pos(compiler_option["-t"], 'f') <> 0 then 7142 trace_function := TRUE; 7143 end if; 7144 if pos(compiler_option["-t"], 's') <> 0 then 7145 trace_signal := TRUE; 7146 end if; 7147 end if; 7148 if "-p" in compiler_option then 7149 profile_function := TRUE; 7150 end if; 7151 if "-e" in compiler_option then 7152 signal_exception := TRUE; 7153 end if; 7154 if "-o" in compiler_option and compiler_option["-o"] in {"c0", "c1", "c2", "c3"} then 7155 evaluate_const_expr := integer(compiler_option["-o"][2 ..]); 7156 end if; 7157 setOptimizationSettings(evaluate_const_expr); 7158 if "-s" in compiler_option then 7159 if pos(compiler_option["-s"], 'd') <> 0 then 7160 integer_division_check := FALSE; 7161 end if; 7162 if pos(compiler_option["-s"], 'i') <> 0 then 7163 string_index_check := FALSE; 7164 bstring_index_check := FALSE; 7165 array_index_check := FALSE; 7166 ref_list_index_check := FALSE; 7167 end if; 7168 if pos(compiler_option["-s"], 'o') <> 0 then 7169 integer_overflow_check := FALSE; 7170 end if; 7171 if pos(compiler_option["-s"], 'r') <> 0 then 7172 function_range_check := FALSE; 7173 conversion_range_check := FALSE; 7174 end if; 7175 end if; 7176 setIntegerDivisionCheck(integer_division_check); 7177 setIntegerOverflowCheck(integer_overflow_check); 7178 if "-c" in compiler_option then 7179 generate_c_plus_plus := compiler_option["-c"] = "++"; 7180 declare_with_extern_c := generate_c_plus_plus; 7181 end if; 7182 if "-f" in compiler_option then 7183 case compiler_option["-f"] of 7184 when {"lto"}: 7185 if ccConf.CC_OPT_LINK_TIME_OPTIMIZATION <> "" then 7186 enable_link_time_optimization := TRUE; 7187 end if; 7188 otherwise: 7189 writeln("*** Ignore unsupported option: -f" <& compiler_option["-f"]); 7190 end case; 7191 end if; 7192 block 7193 prog := parseFile(source, parseOptions.value, libraryDirs); 7194 exception 7195 otherwise: 7196 prog := program.EMPTY; 7197 end block; 7198 if prog = program.EMPTY then 7199 writeln("*** File " <& literal(source) <& " not found or a memory error occurred."); 7200 okay := FALSE; 7201 elsif errorCount(prog) <> 0 then 7202 write(errorCount(prog) <& " error"); 7203 if errorCount(prog) > 1 then 7204 write("s"); 7205 end if; 7206 writeln(" found"); 7207 okay := FALSE; 7208 end if; 7209 else 7210 okay := FALSE; 7211 end if; 7212 end func; 7213 7214 7215const proc: pass_2 (in string: source, in program: prog, 7216 inout boolean: okay) is func 7217 7218 local 7219 var string: temporaryFileName is ""; 7220 var ref_list: globalObjects is ref_list.EMPTY; 7221 var reference: obj is NIL; 7222 begin 7223 if okay then 7224 main_object := sysVar(prog, "main"); 7225 if main_object <> NIL then 7226 compileLibrary := category(main_object) = FORWARDOBJECT; 7227 temporaryFileName := temp_name(source); 7228 if generate_c_plus_plus then 7229 temporaryFileName &:= ".cpp"; 7230 else 7231 temporaryFileName &:= ".c"; 7232 end if; 7233 # The temporary tmp_*.c file is marked with a temp_marker. 7234 # The temp_marker is checked, before the file is overwritten. 7235 c_prog := open(temporaryFileName, "r"); 7236 if c_prog <> STD_NULL then 7237 if getln(c_prog) <> temp_marker then 7238 write("*** The file "); 7239 write(literal(temporaryFileName)); 7240 writeln(" was not created by the compiler."); 7241 write("*** Remove the file "); 7242 write(literal(temporaryFileName)); 7243 writeln(" manually and restart the compiler."); 7244 okay := FALSE; 7245 end if; 7246 close(c_prog); 7247 end if; 7248 if okay then 7249 c_prog := open(temporaryFileName, "w"); 7250 if c_prog <> STD_NULL then 7251 writeln("Generating code ..."); 7252 init_systypes(prog); 7253 write_file_head; 7254 write_prototypes; 7255 write_resize_catch_stack; 7256 globalObjects := globalObjects(prog); 7257 if compileLibrary then 7258 writeln("Compile library"); 7259 for obj range globalObjects do 7260 if endsWith(path(prog), file(obj)) then 7261 process_object(obj); 7262 else 7263 process_library_import_object(obj); 7264 end if; 7265 end for; 7266 else 7267 for obj range globalObjects do 7268 process_object(obj); 7269 end for; 7270 end if; 7271 process_global_declarations(prog); 7272 close(c_prog); 7273 writeln(countDeclarations <& " declarations processed"); 7274 writeln(countOptimizations <& " optimizations done"); 7275 if countEvaluations <> 0 then 7276 writeln(countEvaluations <& " evaluations done"); 7277 end if; 7278 if countRangeChecks <> 0 then 7279 writeln(countRangeChecks <& " range checks inserted"); 7280 end if; 7281 if countNoRangeChecks <> 0 then 7282 writeln(countNoRangeChecks <& " range checks suppressed"); 7283 end if; 7284 if countIndexChecks <> 0 then 7285 writeln(countIndexChecks <& " index checks inserted"); 7286 end if; 7287 if countNoIndexChecks <> 0 then 7288 writeln(countNoIndexChecks <& " index checks suppressed"); 7289 end if; 7290 if countOverflowChecks <> 0 then 7291 writeln(countOverflowChecks <& " overflow checks inserted"); 7292 end if; 7293 else 7294 write("*** Cannot open temp file "); 7295 write(literal(temporaryFileName)); 7296 writeln("."); 7297 okay := FALSE; 7298 end if; 7299 end if; 7300 else 7301 writeln("*** main not found."); 7302 okay := FALSE; 7303 end if; 7304 end if; 7305 end func; 7306 7307 7308const proc: importEnvironment (in string: fileName) is func 7309 local 7310 var iniDataType: iniData is iniDataType.value; 7311 var string: aKey is ""; 7312 var string: aValue is ""; 7313 begin 7314 iniData := readIniFile(fileName); 7315 if "" in iniData then 7316 for aValue key aKey range iniData[""] do 7317 # writeln(aKey <& "=" <& aValue); 7318 setenv(aKey, aValue); 7319 end for; 7320 else 7321 writeln("*** C compiler environment file " <& literal(fileName) <& " not found."); 7322 end if; 7323 end func; 7324 7325 7326const proc: appendLibrary (inout array string: options, in string: libraryToAppend) is func 7327 local 7328 var string: existingOption is ""; 7329 var boolean: found is FALSE; 7330 begin 7331 if libraryToAppend <> "" then 7332 for existingOption range options until found do 7333 found := existingOption = libraryToAppend; 7334 end for; 7335 if not found then 7336 options &:= libraryToAppend; 7337 end if; 7338 end if; 7339 end func; 7340 7341 7342const proc: appendLibrary (inout array string: options, in array string: librariesToAppend) is func 7343 local 7344 var string: libraryToAppend is ""; 7345 begin 7346 for libraryToAppend range librariesToAppend do 7347 appendLibrary(options, libraryToAppend); 7348 end for; 7349 end func; 7350 7351 7352const proc: logProgram (in string: command, in array string: parameters, 7353 in string: errorFile) is func 7354 7355 begin 7356 write(toShellPath(command) <& " " <& shellParameters(parameters)); 7357 case ccConf.CC_ERROR_FILEDES of 7358 when {1}: 7359 write(" " <& ccConf.REDIRECT_FILEDES_1 <& toShellPath(errorFile)); 7360 write(" " <& ccConf.REDIRECT_FILEDES_2 <& ccConf.NULL_DEVICE); 7361 when {2}: 7362 write(" " <& ccConf.REDIRECT_FILEDES_2 <& toShellPath(errorFile)); 7363 write(" " <& ccConf.REDIRECT_FILEDES_1 <& ccConf.NULL_DEVICE); 7364 end case; 7365 writeln; 7366 flush(OUT); 7367 end func; 7368 7369 7370const proc: execProgramScript (in string: command, in array string: parameters, 7371 in string: errorFile) is func 7372 7373 local 7374 var array string: redirection is 0 times ""; 7375 begin 7376 logProgram(command, parameters, errorFile); 7377 case ccConf.CC_ERROR_FILEDES of 7378 when {1}: 7379 redirection &:= ccConf.REDIRECT_FILEDES_1 & toShellPath(errorFile); 7380 redirection &:= ccConf.REDIRECT_FILEDES_2 & ccConf.NULL_DEVICE; 7381 when {2}: 7382 redirection &:= ccConf.REDIRECT_FILEDES_2 & toShellPath(errorFile); 7383 redirection &:= ccConf.REDIRECT_FILEDES_1 & ccConf.NULL_DEVICE; 7384 end case; 7385 if length(redirection) = 0 then 7386 # An CC_ERROR_FILEDES of zero means: Do not redirect. 7387 cmd_sh(command, shellParameters(parameters)); 7388 else 7389 cmd_sh(command, shellParameters(parameters) <& " " <& join(redirection, " ")); 7390 end if 7391 end func; 7392 7393 7394const proc: execProgram (in string: command, in array string: parameters, 7395 in string: errorFile) is func 7396 7397 local 7398 var file: childStdout is STD_NULL; 7399 var file: childStderr is STD_NULL; 7400 var process: aProcess is process.value; 7401 begin 7402 logProgram(command, parameters, errorFile); 7403 case ccConf.CC_ERROR_FILEDES of 7404 when {1}: 7405 childStdout := open(errorFile, "w"); 7406 if childStdout = STD_NULL then 7407 writeln("*** Could not open " <& errorFile); 7408 end if; 7409 when {2}: 7410 childStderr := open(errorFile, "w"); 7411 if childStderr = STD_NULL then 7412 writeln("*** Could not open " <& errorFile); 7413 end if; 7414 end case; 7415 aProcess := startProcess(commandPath(command), parameters, STD_IN, childStdout, childStderr); 7416 waitFor(aProcess); 7417 case ccConf.CC_ERROR_FILEDES of 7418 when {1}: close(childStdout); 7419 when {2}: close(childStderr); 7420 end case; 7421 end func; 7422 7423 7424const proc: pass_3 (in string: sourcePath, in string: sourceExtension, in program: prog, 7425 inout boolean: okay) is func 7426 7427 local 7428 var string: s7_lib_dir is ""; 7429 var string: seed7_lib is ""; 7430 var string: draw_lib is ""; 7431 var string: console_lib is ""; 7432 var string: database_lib is ""; 7433 var string: comp_data_lib is ""; 7434 var string: compiler_lib is ""; 7435 var string: special_lib is ""; 7436 var string: cwd is ""; 7437 var string: workDir is ""; 7438 var string: sourceFile is ""; 7439 var string: cSourceFile is ""; 7440 var string: cErrorFile is ""; 7441 var string: objectFile is ""; 7442 var string: linkErrFile is ""; 7443 var string: tempExeFile is ""; 7444 var string: linkedProgram is ""; 7445 var string: compile_cmd is ""; 7446 var array string: compileParams is 0 times ""; 7447 var string: link_cmd is ""; 7448 var array string: linkParams is 0 times ""; 7449 begin 7450 if okay then 7451 writeln("Calling the C compiler ..."); 7452 if ccConf.CC_ENVIRONMENT_INI <> "" then 7453 importEnvironment(ccConf.CC_ENVIRONMENT_INI); 7454 end if; 7455 if "-b" in compiler_option then 7456 s7_lib_dir := convDosPath(compiler_option["-b"]); 7457 else 7458 s7_lib_dir := ccConf.S7_LIB_DIR; 7459 end if; 7460 seed7_lib := s7_lib_dir & "/" & ccConf.SEED7_LIB; 7461 draw_lib := s7_lib_dir & "/" & ccConf.DRAW_LIB; 7462 console_lib := s7_lib_dir & "/" & ccConf.CONSOLE_LIB; 7463 database_lib := s7_lib_dir & "/" & ccConf.DATABASE_LIB; 7464 comp_data_lib := s7_lib_dir & "/" & ccConf.COMP_DATA_LIB; 7465 compiler_lib := s7_lib_dir & "/" & ccConf.COMPILER_LIB; 7466 special_lib := s7_lib_dir & "/" & ccConf.SPECIAL_LIB; 7467 cwd := getcwd(); 7468 if rpos(sourcePath, "/") = 0 then 7469 sourceFile := sourcePath; 7470 else 7471 if rpos(sourcePath, "/") = 1 then 7472 chdir("/"); 7473 else 7474 chdir(sourcePath[.. pred(rpos(sourcePath, "/"))]); 7475 end if; 7476 workDir := sourcePath[.. rpos(sourcePath, "/")]; 7477 sourceFile := sourcePath[succ(rpos(sourcePath, "/")) ..]; 7478 end if; 7479 cSourceFile := "tmp_" & sourceFile; 7480 if generate_c_plus_plus then 7481 cSourceFile &:= ".cpp"; 7482 else 7483 cSourceFile &:= ".c"; 7484 end if; 7485 cErrorFile := "tmp_" & sourceFile & ".cerrs"; 7486 objectFile := "tmp_" & sourceFile & ccConf.OBJECT_FILE_EXTENSION; 7487 linkErrFile := "tmp_" & sourceFile & ".lerrs"; 7488 tempExeFile := "tmp_" & sourceFile & ccConf.LINKED_PROGRAM_EXTENSION; 7489 if sourceExtension = "" and ccConf.LINKED_PROGRAM_EXTENSION = "" then 7490 linkedProgram := sourceFile & "_exe"; 7491 else 7492 linkedProgram := sourceFile & ccConf.LINKED_PROGRAM_EXTENSION; 7493 end if; 7494 if fileType(objectFile) = FILE_REGULAR then 7495 removeFile(objectFile); 7496 end if; 7497 if generate_c_plus_plus then 7498 compile_cmd := ccConf.CPLUSPLUS_COMPILER; 7499 else 7500 compile_cmd := ccConf.C_COMPILER; 7501 end if; 7502 compileParams &:= ccConf.CC_OPT_NO_WARNINGS; 7503 if enable_link_time_optimization then 7504 compileParams &:= ccConf.CC_OPT_LINK_TIME_OPTIMIZATION; 7505 end if; 7506 if "-O" in compiler_option then 7507 case compiler_option["-O"] of 7508 when {"", "1"}: 7509 compileParams &:= ccConf.CC_OPT_OPTIMIZE_1; 7510 when {"2"}: 7511 compileParams &:= ccConf.CC_OPT_OPTIMIZE_2; 7512 when {"3"}: 7513 compileParams &:= ccConf.CC_OPT_OPTIMIZE_3; 7514 otherwise: 7515 writeln("*** Ignore unsupported option: -O" <& compiler_option["-O"]); 7516 end case; 7517 end if; 7518 if integer_overflow_check and ccConf.CC_OPT_TRAP_OVERFLOW <> "" then 7519 compileParams &:= ccConf.CC_OPT_TRAP_OVERFLOW; 7520 end if; 7521 if "-g" in compiler_option then 7522 compileParams &:= ccConf.CC_OPT_DEBUG_INFO; 7523 if compiler_option["-g"] <> "" and compiler_option["-g"] <> "-debug_c" then 7524 compileParams &:= compiler_option["-g"]; 7525 end if; 7526 end if; 7527 if length(ccConf.CC_FLAGS) <> 0 then 7528 compileParams &:= ccConf.CC_FLAGS; 7529 end if; 7530 compileParams &:= "-c"; 7531 compileParams &:= toOsPath(cSourceFile); 7532 if ccConf.CALL_C_COMPILER_FROM_SHELL then 7533 execProgramScript(compile_cmd, compileParams, cErrorFile); 7534 else 7535 execProgram(compile_cmd, compileParams, cErrorFile); 7536 end if; 7537 if fileType(cErrorFile) = FILE_REGULAR and 7538 fileSize(cErrorFile) = 0 then 7539 removeFile(cErrorFile); 7540 end if; 7541 if fileType(objectFile) <> FILE_REGULAR then 7542 if fileType(cErrorFile) = FILE_REGULAR then 7543 writeln("*** Errors in " <& literal(workDir & cSourceFile) <& 7544 " - see " <& literal(workDir & cErrorFile)); 7545 elsif ccConf.CC_ERROR_FILEDES not in {1, 2} then 7546 writeln("*** Compilation terminated"); 7547 else 7548 writeln("*** Compilation terminated without error messages"); 7549 end if; 7550 okay := FALSE; 7551 elsif fileType(cErrorFile) = FILE_REGULAR then 7552 removeFile(cErrorFile); 7553 end if; 7554 if okay then 7555 if "-g" not in compiler_option then 7556 removeFile(cSourceFile); 7557 end if; 7558 if compilerLibraryUsed then 7559 drawLibraryUsed := TRUE; 7560 consoleLibraryUsed := TRUE; 7561 databaseLibraryUsed := TRUE; 7562 end if; 7563 if fileType(seed7_lib) <> FILE_REGULAR then 7564 writeln("*** Seed7 library " <& literal(seed7_lib) <& " missing"); 7565 okay := FALSE; 7566 end if; 7567 if drawLibraryUsed and fileType(draw_lib) <> FILE_REGULAR then 7568 writeln("*** Draw library " <& literal(draw_lib) <& " missing"); 7569 okay := FALSE; 7570 end if; 7571 if consoleLibraryUsed and fileType(console_lib) <> FILE_REGULAR then 7572 writeln("*** Console library " <& literal(console_lib) <& " missing"); 7573 okay := FALSE; 7574 end if; 7575 if databaseLibraryUsed and fileType(database_lib) <> FILE_REGULAR then 7576 writeln("*** Database library " <& literal(database_lib) <& " missing"); 7577 okay := FALSE; 7578 end if; 7579 if compilerLibraryUsed and fileType(compiler_lib) <> FILE_REGULAR then 7580 writeln("*** Compiler library " <& literal(compiler_lib) <& " missing"); 7581 okay := FALSE; 7582 end if; 7583 if compDataLibraryUsed and fileType(comp_data_lib) <> FILE_REGULAR then 7584 writeln("*** Compiler data library " <& literal(comp_data_lib) <& " missing"); 7585 okay := FALSE; 7586 end if; 7587 if ccConf.LINKER_OPT_SPECIAL_LIB <> "" and fileType(special_lib) <> FILE_REGULAR then 7588 writeln("*** Special library " <& literal(compiler_lib) <& " missing"); 7589 okay := FALSE; 7590 end if; 7591 if okay and not compileLibrary then 7592 if fileType(linkedProgram) = FILE_REGULAR then 7593 block 7594 removeFile(linkedProgram); 7595 exception 7596 catch FILE_ERROR: 7597 writeln("*** Cannot remove old executable: " <& 7598 literal(linkedProgram)); 7599 end block; 7600 end if; 7601 if fileType(linkedProgram) = FILE_ABSENT then 7602 writeln("Calling the linker ..."); 7603 if generate_c_plus_plus then 7604 link_cmd := ccConf.CPLUSPLUS_COMPILER; 7605 else 7606 link_cmd := ccConf.C_COMPILER; 7607 end if; 7608 if enable_link_time_optimization or ccConf.LINKER_OPT_LTO_MANDATORY then 7609 linkParams &:= ccConf.CC_OPT_LINK_TIME_OPTIMIZATION; 7610 end if; 7611 if "-g" in compiler_option then 7612 if ccConf.LINKER_OPT_DEBUG_INFO <> "" then 7613 linkParams &:= ccConf.LINKER_OPT_DEBUG_INFO; 7614 end if; 7615 else 7616 if ccConf.LINKER_OPT_NO_DEBUG_INFO <> "" then 7617 linkParams &:= ccConf.LINKER_OPT_NO_DEBUG_INFO; 7618 end if; 7619 end if; 7620 linkParams &:= ccConf.LINKER_FLAGS; 7621 if ccConf.LINKER_OPT_OUTPUT_FILE <> "" then 7622 if endsWith(ccConf.LINKER_OPT_OUTPUT_FILE, " ") then 7623 linkParams &:= rtrim(ccConf.LINKER_OPT_OUTPUT_FILE); 7624 linkParams &:= toOsPath(linkedProgram); 7625 else 7626 linkParams &:= ccConf.LINKER_OPT_OUTPUT_FILE & 7627 toOsPath(linkedProgram); 7628 end if; 7629 end if; 7630 linkParams &:= toOsPath(objectFile); 7631 if compilerLibraryUsed then 7632 appendLibrary(linkParams, toOsPath(compiler_lib)); 7633 end if; 7634 if compDataLibraryUsed then 7635 appendLibrary(linkParams, toOsPath(comp_data_lib)); 7636 end if; 7637 if drawLibraryUsed then 7638 appendLibrary(linkParams, toOsPath(draw_lib)); 7639 end if; 7640 if consoleLibraryUsed then 7641 appendLibrary(linkParams, toOsPath(console_lib)); 7642 end if; 7643 if databaseLibraryUsed then 7644 appendLibrary(linkParams, toOsPath(database_lib)); 7645 end if; 7646 appendLibrary(linkParams, toOsPath(seed7_lib)); 7647 if ccConf.LINKER_OPT_SPECIAL_LIB <> "" then 7648 appendLibrary(linkParams, ccConf.LINKER_OPT_SPECIAL_LIB); 7649 appendLibrary(linkParams, toOsPath(special_lib)); 7650 end if; 7651 appendLibrary(linkParams, ccConf.SYSTEM_LIBS); 7652 if bigintLibraryUsed then 7653 appendLibrary(linkParams, ccConf.SYSTEM_BIGINT_LIBS); 7654 end if; 7655 if consoleLibraryUsed then 7656 appendLibrary(linkParams, ccConf.SYSTEM_CONSOLE_LIBS); 7657 end if; 7658 if databaseLibraryUsed then 7659 appendLibrary(linkParams, ccConf.SYSTEM_DATABASE_LIBS); 7660 end if; 7661 if drawLibraryUsed then 7662 appendLibrary(linkParams, ccConf.SYSTEM_DRAW_LIBS); 7663 end if; 7664 if mathLibraryUsed then 7665 appendLibrary(linkParams, ccConf.SYSTEM_MATH_LIBS); 7666 end if; 7667 if ccConf.CALL_C_COMPILER_FROM_SHELL then 7668 execProgramScript(link_cmd, linkParams, linkErrFile); 7669 else 7670 execProgram(link_cmd, linkParams, linkErrFile); 7671 end if; 7672 if ccConf.LINKER_OPT_OUTPUT_FILE = "" and 7673 fileType(tempExeFile) = FILE_REGULAR then 7674 moveFile(tempExeFile, linkedProgram); 7675 end if; 7676 if fileType(linkedProgram) <> FILE_REGULAR then 7677 if fileType(linkErrFile) = FILE_REGULAR and 7678 fileSize(linkErrFile) = 0 then 7679 removeFile(linkErrFile); 7680 end if; 7681 if fileType(linkErrFile) = FILE_REGULAR then 7682 writeln("*** Linker errors with " <& literal(workDir & objectFile) <& 7683 " - see " <& literal(workDir & linkErrFile)); 7684 elsif ccConf.CC_ERROR_FILEDES not in {1, 2} then 7685 writeln("*** Linking terminated"); 7686 else 7687 writeln("*** Linking terminated without error messages"); 7688 end if; 7689 elsif fileType(linkErrFile) = FILE_REGULAR then 7690 removeFile(linkErrFile); 7691 end if; 7692 if "-g" not in compiler_option then 7693 removeFile(objectFile); 7694 end if; 7695 end if; 7696 end if; 7697 end if; 7698 chdir(cwd); 7699 end if; 7700 end func; 7701 7702 7703const proc: writeHelp is func 7704 begin 7705 writeln("usage: s7c [options] source"); 7706 writeln; 7707 writeln("Options:"); 7708 writeln(" -? Write Seed7 compiler usage."); 7709 writeln(" -O and -O2 Tell the C compiler to optimize."); 7710 writeln(" -b Specify the directory of the Seed7 runtime libraries (e.g.: -b ../bin)."); 7711 writeln(" -e Generate code which sends a signal, if an uncaught exception occurs."); 7712 writeln(" This option allows debuggers to handle uncaught Seed7 exceptions."); 7713 writeln(" -flto Enable link time optimization."); 7714 writeln(" -g Tell the C compiler to generate an executable with debug information."); 7715 writeln(" This way the debugger will refer to Seed7 source files and line numbers."); 7716 writeln(" To generate debug information which refers to the temporary C program"); 7717 writeln(" the option -g-debug_c can be used."); 7718 writeln(" -l Add a directory to the include library search path (e.g.: -l ../lib)."); 7719 writeln(" -ocn Optimize constants with level n. E.g.: -oc3"); 7720 writeln(" The level n is a digit between 0 and 3:"); 7721 writeln(" 0 Do no optimizations with constants."); 7722 writeln(" 1 Use literals and named constants to simplify expressions (default)."); 7723 writeln(" 2 Evaluate constant parameter expressions to simplify expressions."); 7724 writeln(" 3 Like -oc2 and additionally evaluate all constant expressions."); 7725 writeln(" -p Activate simple function profiling."); 7726 writeln(" -sx Suppress checks specified with x. E.g.: -sr or -sro"); 7727 writeln(" The checks x are specified with letters from the following list:"); 7728 writeln(" d Suppress the generation of checks for integer division by zero."); 7729 writeln(" i Suppress the generation of index checks (e.g. string, array)."); 7730 writeln(" o Suppress the generation of integer overflow checks."); 7731 writeln(" r Suppress the generation of range checks."); 7732 writeln(" -tx Set runtime trace level to x. Where x is a string consisting of:"); 7733 writeln(" e Trace exceptions and handlers"); 7734 writeln(" f Trace functions"); 7735 writeln(" s Trace signals"); 7736 writeln; 7737 end func; 7738 7739 7740const proc: main is func 7741 7742 local 7743 var integer: index is 0; 7744 var string: curr_arg is ""; 7745 var string: source is ""; 7746 var string: sourcePath is ""; 7747 var string: sourceExtension is ""; 7748 var boolean: okay is TRUE; 7749 7750 begin 7751 OUT := STD_UTF8_OUT; 7752 writeln("SEED7 COMPILER Version 3.1." <& ccConf.VERSION_REVISION_LEVEL <& 7753 " Copyright (c) 1990-2021 Thomas Mertes"); 7754 if length(argv(PROGRAM)) = 0 then 7755 writeln("This is free software; see the source for copying conditions. There is NO"); 7756 writeln("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."); 7757 writeln("S7c is written in the Seed7 programming language"); 7758 writeln("Homepage: http://seed7.sourceforge.net"); 7759 writeln; 7760 writeln("usage: s7c [options] source"); 7761 writeln; 7762 writeln("Use s7c -? to get more information about s7c."); 7763 writeln; 7764 else 7765 for index range 1 to length(argv(PROGRAM)) do 7766 curr_arg := argv(PROGRAM)[index]; 7767 if length(curr_arg) >= 2 and curr_arg[1] = '-' then 7768 if curr_arg in {"-b"} and index < length(argv(PROGRAM)) then 7769 incr(index); 7770 compiler_option @:= [curr_arg] argv(PROGRAM)[index]; 7771 elsif curr_arg in {"-l"} and index < length(argv(PROGRAM)) then 7772 incr(index); 7773 libraryDirs &:= convDosPath(argv(PROGRAM)[index]); 7774 elsif curr_arg[.. 2] in {"-?", "-b", "-c", "-e", "-f", "-g", "-o", "-p", "-s", "-t", "-O"} then 7775 if curr_arg[.. 2] in compiler_option then 7776 writeln("*** Option " <& curr_arg[.. 2] <& 7777 " specified twice. Ignore option: " <& curr_arg); 7778 else 7779 compiler_option @:= [curr_arg[.. 2]] curr_arg[3 ..]; 7780 end if; 7781 else 7782 writeln("*** Ignore unsupported option: " <& curr_arg); 7783 end if; 7784 elsif source = "" then 7785 source := convDosPath(curr_arg); 7786 else 7787 writeln("*** Ignore superfluous parameter: " <& curr_arg); 7788 end if; 7789 end for; 7790 if "-?" in compiler_option then 7791 writeHelp; 7792 elsif source = "" then 7793 writeln("*** Sourcefile missing"); 7794 else 7795 writeln("Source: " <& source); 7796 pass_1(source, prog, okay); 7797 if okay then 7798 sourcePath := path(prog); 7799 if endsWith(sourcePath, ".sd7") or 7800 endsWith(sourcePath, ".s7i") then 7801 sourceExtension := sourcePath[length(sourcePath) - 3 ..]; 7802 sourcePath := sourcePath[.. length(sourcePath) - 4]; 7803 end if; 7804 end if; 7805 pass_2(sourcePath, prog, okay); 7806 pass_3(sourcePath, sourceExtension, prog, okay); 7807 end if; 7808 end if; 7809 end func; 7810