try to make things work on 64 bit systems
Annotate for file src/snc/parse.c
2000-04-04 William 1 /*#define DEBUG 1*/
03:23:15 ' 2 /**************************************************************************
' 3 GTA PROJECT AT division
' 4 Copyright, 1990, The Regents of the University of California.
' 5 Los Alamos National Laboratory
' 6
' 7 < parse.c,v 1.3 1995/10/19 16:30:16 wright Exp
' 8 DESCRIPTION: Parsing support routines for state notation compiler.
' 9 The 'yacc' parser calls these routines to build the tables
' 10 and linked lists, which are then passed on to the phase 2 routines.
' 11
' 12 ENVIRONMENT: UNIX
' 13 HISTORY:
' 14 19nov91,ajk Replaced lstLib calls with built-in links.
' 15 20nov91,ajk Removed snc_init() - no longer did anything useful.
' 16 20nov91,ajk Added option_stmt() routine.
' 17 28apr92,ajk Implemented new event flag mode.
' 18 29opc93,ajk Implemented assignment of pv's to array elements.
' 19 29oct93,ajk Implemented variable class (VC_SIMPLE, VC_ARRAY, & VC_POINTER).
' 20 29oct93,ajk Added 'v' (vxWorks include) option.
' 21 17may94,ajk Removed old event flag (-e) option.
' 22 08aug96,wfl Added new syncq_stmt() routine.
' 23 29apr99,wfl Avoided compilation warnings; removed unused vx_opt option.
' 24 17may99,wfl Fixed crash in debug output.
' 25 06jul99,wfl Added "+m" (main) option.
' 26 07sep99,wfl Added E_DECL expression type (for local declarations).
' 27 22sep99,grw Supported entry and exit actions; supported state options.
' 28 06mar00,wfl Avoided NULL pointer crash when DEBUG is enabled.
' 29 31mar00,wfl Supported entry handler.
' 30 ***************************************************************************/
' 31
' 32 /*====================== Includes, globals, & defines ====================*/
' 33 #include <ctype.h>
' 34 #include <math.h>
' 35 #include <stdio.h>
' 36 #include <stdlib.h>
' 37 #include <string.h>
' 38
' 39 #include "parse.h" /* defines linked list structures */
' 40 #include "proto.h" /* function prototypes */
' 41
' 42 #ifndef TRUE
' 43 #define TRUE 1
' 44 #define FALSE 0
' 45 #endif /*TRUE*/
' 46
' 47 int debug_print_opt = 0; /* Debug level (set by source file) */
' 48
' 49 char *prog_name; /* ptr to program name (string) */
' 50
' 51 char *prog_param; /* parameter string for program stmt */
' 52
' 53 Expr *defn_c_list; /* definition C code list */
' 54
' 55 Expr *ss_list; /* Start of state set list */
' 56
' 57 Expr *entry_code_list; /* Start of entry code list */
' 58
' 59 Expr *exit_code_list; /* Start of exit code list */
' 60
' 61 Var *var_list = NULL; /* start of variable list */
' 62 Var *var_tail = NULL; /* tail of variable list */
' 63
' 64 Chan *chan_list = NULL; /* start of DB channel list */
' 65 Chan *chan_tail = NULL; /* tail of DB channel list */
' 66
' 67 Expr *global_c_list; /* global C code following state program */
' 68
2010-03-01 ben.franksen 69 Chan *build_db_struct(Var *vp);
21:37:20 ' 70 void alloc_db_lists(Chan *cp, int length);
' 71 void addVar(Var *vp);
' 72 void addChan(Chan *cp);
2000-04-04 William 73
03:23:15 ' 74 /*+************************************************************************
' 75 * NAME: program_name
' 76 *
' 77 * CALLING SEQUENCE: none
' 78 * type argument I/O description
' 79 * -----------------------------------------------------------------
' 80 * char *pname I ptr to program name string
' 81 *
' 82 * RETURNS:
' 83 *
' 84 * FUNCTION: Save program name for global use.
' 85 *
' 86 *-*************************************************************************/
2010-03-01 ben.franksen 87 void program_name(char *pname, char *pparam)
2000-04-04 William 88 {
03:23:15 ' 89 prog_name = pname;
' 90 prog_param = pparam;
' 91 #ifdef DEBUG
' 92 fprintf(stderr, "program name = %s\n", prog_name);
' 93 #endif /*DEBUG*/
' 94 return;
' 95 }
' 96
' 97 /* Parsing a declaration statement */
2010-03-01 ben.franksen 98 void decl_stmt(
21:37:20 ' 99 int type, /* variable type (e.g. V_FLOAT) */
' 100 int class, /* variable class (e.g. VC_ARRAY) */
' 101 char *name, /* ptr to variable name */
' 102 char *s_length1, /* array lth (1st dim, arrays only) */
' 103 char *s_length2, /* array lth (2nd dim, [n]x[m] arrays only) */
' 104 char *value /* initial value or NULL */
' 105 )
2000-04-04 William 106 {
03:23:15 ' 107 Var *vp;
' 108 int length1, length2;
' 109 extern int line_num;
' 110
' 111 #ifdef DEBUG
' 112 fprintf(stderr,
' 113 "variable decl: type=%d, class=%d, name=%s, ", type, class, name);
' 114 #endif /*DEBUG*/
' 115 length1 = length2 = 1;
' 116
' 117 if (s_length1 != NULL)
' 118 {
' 119 length1 = atoi(s_length1);
' 120 if (length1 <= 0)
' 121 length1 = 1;
' 122 }
' 123
' 124 if (s_length2 != NULL)
' 125 {
' 126 length2 = atoi(s_length2);
' 127 if (length2 <= 0)
' 128 length2 = 1;
' 129 }
' 130
' 131 #ifdef DEBUG
' 132 fprintf(stderr, "length1=%d, length2=%d\n", length1, length2);
' 133 #endif /*DEBUG*/
' 134 /* See if variable already declared */
' 135 vp = (Var *)findVar(name);
' 136 if (vp != 0)
' 137 {
' 138 fprintf(stderr, "variable %s already declared, line %d\n",
' 139 name, line_num);
' 140 return;
' 141 }
' 142 /* Build a struct for this variable */
' 143 vp = allocVar();
' 144 addVar(vp); /* add to var list */
' 145 vp->name = name;
' 146 vp->class = class;
' 147 vp->type = type;
' 148 vp->length1 = length1;
' 149 vp->length2 = length2;
' 150 vp->value = value; /* initial value or NULL */
' 151 vp->chan = NULL;
' 152 return;
' 153 }
' 154
' 155 /* Option statement */
2010-03-01 ben.franksen 156 void option_stmt(
21:37:20 ' 157 char *option, /* "a", "r", ... */
' 158 int value /* TRUE means +, FALSE means - */
' 159 )
2000-04-04 William 160 {
2001-03-19 Marty 161 extern int async_opt, conn_opt, debug_opt, line_opt, init_reg_opt,
2000-04-04 William 162 reent_opt, warn_opt, newef_opt, main_opt;
03:23:15 ' 163
' 164 switch(*option)
' 165 {
' 166 case 'a':
' 167 async_opt = value;
' 168 break;
' 169 case 'c':
' 170 conn_opt = value;
' 171 break;
' 172 case 'd':
' 173 debug_opt = value;
' 174 break;
' 175 case 'e':
' 176 newef_opt = value;
' 177 break;
2001-03-19 Marty 178 case 'i':
21:07:52 ' 179 init_reg_opt = value;
' 180 break;
2000-04-04 William 181 case 'l':
03:23:15 ' 182 line_opt = value;
' 183 break;
' 184 case 'm':
' 185 main_opt = value;
' 186 break;
' 187 case 'r':
' 188 reent_opt = value;
' 189 break;
' 190 case 'w':
' 191 warn_opt = value;
' 192 break;
' 193 }
' 194 return;
' 195 }
' 196
2011-04-06 ben.franksen 197 int check_type_too_long(Var *vp)
18:59:29 ' 198 {
' 199 extern int line_num;
' 200
' 201 if ((sizeof(long) > 4 && (vp->type == V_LONG || vp->type == V_ULONG))
' 202 || (sizeof(int) > 4 && (vp->type == V_INT || vp->type == V_UINT)))
' 203 {
' 204 fprintf(stderr,
' 205 "line %d: cannot assign variable >%s< because on this architecture "
' 206 "its (base) type is larger than 4 bytes. Such variables cannot be faithfully "
' 207 "mapped to any of the Channel Access base types.\nTry declaring the "
' 208 "variable as 'int' or, if that is still too large on your system, as 'short'.\n",
' 209 line_num, vp->name);
' 210 return FALSE;
' 211 }
' 212 return TRUE;
' 213 }
' 214
2000-04-04 William 215 /* "Assign" statement: Assign a variable to a DB channel.
03:23:15 ' 216 * Format: assign <variable> to <string;
' 217 * Note: Variable may be subscripted.
' 218 */
2010-03-01 ben.franksen 219 void assign_single(
21:37:20 ' 220 char *name, /* ptr to variable name */
' 221 char *db_name /* ptr to db name */
' 222 )
2000-04-04 William 223 {
03:23:15 ' 224 Chan *cp;
' 225 Var *vp;
' 226 extern int line_num;
' 227
' 228 #ifdef DEBUG
' 229 fprintf(stderr, "assign %s to \"%s\";\n", name, db_name);
' 230 #endif /*DEBUG*/
' 231 /* Find the variable */
' 232 vp = (Var *)findVar(name);
' 233 if (vp == 0)
' 234 {
' 235 fprintf(stderr, "assign: variable %s not declared, line %d\n",
' 236 name, line_num);
' 237 return;
' 238 }
' 239
' 240 cp = vp->chan;
' 241 if (cp != NULL)
' 242 {
' 243 fprintf(stderr, "assign: %s already assigned, line %d\n",
' 244 name, line_num);
' 245 return;
' 246 }
' 247
2011-04-06 ben.franksen 248 if (!check_type_too_long(vp)) return;
18:59:29 ' 249
2000-04-04 William 250 /* Build structure for this channel */
03:23:15 ' 251 cp = build_db_struct(vp);
' 252
' 253 cp->db_name = db_name; /* DB name */
' 254
' 255 /* The entire variable is assigned */
' 256 cp->count = vp->length1 * vp->length2;
' 257
' 258 return;
' 259 }
' 260
' 261 /* "Assign" statement: assign an array element to a DB channel.
' 262 * Format: assign <variable>[<subscr>] to <string>; */
2010-03-01 ben.franksen 263 void assign_subscr(
21:37:20 ' 264 char *name, /* ptr to variable name */
' 265 char *subscript, /* subscript value or NULL */
' 266 char *db_name /* ptr to db name */
' 267 )
2000-04-04 William 268 {
03:23:15 ' 269 Chan *cp;
' 270 Var *vp;
' 271 int subNum;
' 272 extern int line_num;
' 273
' 274 #ifdef DEBUG
' 275 fprintf(stderr, "assign %s[%s] to \"%s\";\n", name, subscript, db_name);
' 276 #endif /*DEBUG*/
' 277 /* Find the variable */
' 278 vp = (Var *)findVar(name);
' 279 if (vp == 0)
' 280 {
' 281 fprintf(stderr, "assign: variable %s not declared, line %d\n",
' 282 name, line_num);
' 283 return;
' 284 }
' 285
' 286 if (vp->class != VC_ARRAY1 && vp->class != VC_ARRAY2)
' 287 {
' 288 fprintf(stderr, "assign: variable %s not an array, line %d\n",
' 289 name, line_num);
' 290 return;
' 291 }
' 292
2011-04-06 ben.franksen 293 if (!check_type_too_long(vp)) return;
18:59:29 ' 294
2000-04-04 William 295 cp = vp->chan;
03:23:15 ' 296 if (cp == NULL)
' 297 {
' 298 /* Build structure for this channel */
' 299 cp = build_db_struct(vp);
' 300 }
' 301 else if (cp->db_name != NULL)
' 302 {
' 303 fprintf(stderr, "assign: array %s already assigned, line %d\n",
' 304 name, line_num);
' 305 return;
' 306 }
' 307
' 308 subNum = atoi(subscript);
' 309 if (subNum < 0 || subNum >= vp->length1)
' 310 {
' 311 fprintf(stderr,
' 312 "assign: subscript %s[%d] is out of range, line %d\n",
' 313 name, subNum, line_num);
' 314 return;
' 315 }
' 316
' 317 if (cp->db_name_list == NULL)
' 318 alloc_db_lists(cp, vp->length1); /* allocate lists */
' 319 else if (cp->db_name_list[subNum] != NULL)
' 320 {
' 321 fprintf(stderr, "assign: %s[%d] already assigned, line %d\n",
' 322 name, subNum, line_num);
' 323 return;
' 324 }
' 325
' 326 cp->db_name_list[subNum] = db_name;
' 327 cp->count = vp->length2; /* could be a 2-dimensioned array */
' 328
' 329 return;
' 330 }
' 331
' 332 /* Assign statement: assign an array to multiple DB channels.
' 333 * Format: assign <variable> to { <string>, <string>, ... };
' 334 * Assignments for double dimensioned arrays:
' 335 * <var>[0][0] assigned to 1st db name,
' 336 * <var>[1][0] assigned to 2nd db name, etc.
' 337 * If db name list contains fewer names than the array dimension,
' 338 * the remaining elements receive NULL assignments.
' 339 */
2010-03-01 ben.franksen 340 void assign_list(
21:37:20 ' 341 char *name, /* ptr to variable name */
' 342 Expr *db_name_list /* ptr to db name list */
' 343 )
2000-04-04 William 344 {
03:23:15 ' 345 Chan *cp;
' 346 Var *vp;
' 347 int elem_num;
' 348 extern int line_num;
' 349
' 350 #ifdef DEBUG
' 351 fprintf(stderr, "assign %s to {", name);
' 352 #endif /*DEBUG*/
' 353 /* Find the variable */
' 354 vp = (Var *)findVar(name);
' 355 if (vp == 0)
' 356 {
' 357 fprintf(stderr, "assign: variable %s not declared, line %d\n",
' 358 name, line_num);
' 359 return;
' 360 }
' 361
' 362 if (vp->class != VC_ARRAY1 && vp->class != VC_ARRAY2)
' 363 {
' 364 fprintf(stderr, "assign: variable %s is not an array, line %d\n",
' 365 name, line_num);
' 366 return;
' 367 }
' 368
' 369 cp = vp->chan;
' 370 if (cp != NULL)
' 371 {
' 372 fprintf(stderr, "assign: variable %s already assigned, line %d\n",
' 373 name, line_num);
' 374 return;
' 375 }
' 376
2011-04-06 ben.franksen 377 if (!check_type_too_long(vp)) return;
18:59:29 ' 378
2000-04-04 William 379 /* Build a db structure for this variable */
03:23:15 ' 380 cp = build_db_struct(vp);
' 381
' 382 /* Allocate lists */
' 383 alloc_db_lists(cp, vp->length1); /* allocate lists */
' 384
' 385 /* fill in the array of pv names */
' 386 for (elem_num = 0; elem_num < vp->length1; elem_num++)
' 387 {
' 388 if (db_name_list == NULL)
' 389 break; /* end of list */
' 390
' 391 #ifdef DEBUG
' 392 fprintf(stderr, "\"%s\", ", db_name_list->value);
' 393 #endif /*DEBUG*/
' 394 cp->db_name_list[elem_num] = db_name_list->value; /* DB name */
' 395 cp->count = vp->length2;
' 396
' 397 db_name_list = db_name_list->next;
' 398 }
' 399 #ifdef DEBUG
' 400 fprintf(stderr, "};\n");
' 401 #endif /*DEBUG*/
' 402
' 403 return;
' 404 }
' 405
' 406 /* Build a db structure for this variable */
2010-03-01 ben.franksen 407 Chan *build_db_struct(Var *vp)
2000-04-04 William 408 {
03:23:15 ' 409 Chan *cp;
' 410
' 411 cp = allocChan();
' 412 addChan(cp); /* add to Chan list */
' 413
' 414 /* make connections between Var & Chan structures */
' 415 cp->var = vp;
' 416 vp->chan = cp;
' 417
' 418 /* Initialize the structure */
' 419 cp->db_name_list = 0;
' 420 cp->mon_flag_list = 0;
' 421 cp->ef_var_list = 0;
' 422 cp->ef_num_list = 0;
' 423 cp->num_elem = 0;
' 424 cp->mon_flag = 0;
' 425 cp->ef_var = 0;
' 426 cp->ef_num = 0;
' 427
' 428 return cp;
' 429 }
' 430
' 431 /* Allocate lists for assigning multiple pv's to a variable */
2010-03-01 ben.franksen 432 void alloc_db_lists(Chan *cp, int length)
2000-04-04 William 433 {
03:23:15 ' 434 /* allocate an array of pv names */
' 435 cp->db_name_list = (char **)calloc(sizeof(char **), length);
' 436
' 437 /* allocate an array for monitor flags */
' 438 cp->mon_flag_list = (int *)calloc(sizeof(int **), length);
' 439
' 440 /* allocate an array for event flag var ptrs */
' 441 cp->ef_var_list = (Var **)calloc(sizeof(Var **), length);
' 442
' 443 /* allocate an array for event flag numbers */
' 444 cp->ef_num_list = (int *)calloc(sizeof(int **), length);
' 445
' 446 cp->num_elem = length;
' 447
' 448 }
' 449
' 450 /* Parsing a "monitor" statement.
' 451 * Format:
' 452 * monitor <var>; - monitor a single variable or all elements in an array.
' 453 * monitor <var>[<m>]; - monitor m-th element of an array.
' 454 */
2010-03-01 ben.franksen 455 void monitor_stmt(
21:37:20 ' 456 char *name, /* variable name (should be assigned) */
' 457 char *subscript /* element number or NULL */
' 458 )
2000-04-04 William 459 {
03:23:15 ' 460 Var *vp;
' 461 Chan *cp;
' 462 int subNum;
' 463 extern int line_num;
' 464
' 465 #ifdef DEBUG
' 466 fprintf(stderr, "monitor_stmt: name=%s", name);
' 467 if (subscript != NULL) fprintf(stderr, "[%s]", subscript);
' 468 fprintf(stderr, "\n");
' 469 #endif /*DEBUG*/
' 470
' 471 /* Find the variable */
' 472 vp = (Var *)findVar(name);
' 473 if (vp == 0)
' 474 {
' 475 fprintf(stderr, "assign: variable %s not declared, line %d\n",
' 476 name, line_num);
' 477 return;
' 478 }
' 479
' 480 /* Find a channel assigned to this variable */
' 481 cp = vp->chan;
' 482 if (cp == 0)
' 483 {
' 484 fprintf(stderr, "monitor: variable %s not assigned, line %d\n",
' 485 name, line_num);
' 486 return;
' 487 }
' 488
' 489 if (subscript == NULL)
' 490 {
' 491 if (cp->num_elem == 0)
' 492 { /* monitor one channel for this variable */
' 493 cp->mon_flag = TRUE;
' 494 return;
' 495 }
' 496
' 497 /* else monitor all channels in db list */
' 498 for (subNum = 0; subNum < cp->num_elem; subNum++)
' 499 { /* 1 pv per element of the array */
' 500 cp->mon_flag_list[subNum] = TRUE;
' 501 }
' 502 return;
' 503 }
' 504
' 505 /* subscript != NULL */
' 506 subNum = atoi(subscript);
' 507 if (subNum < 0 || subNum >= cp->num_elem)
' 508 {
' 509 fprintf(stderr, "monitor: subscript of %s out of range, line %d\n",
' 510 name, line_num);
' 511 return;
' 512 }
' 513
' 514 if (cp->num_elem == 0 || cp->db_name_list[subNum] == NULL)
' 515 {
' 516 fprintf(stderr, "monitor: %s[%d] not assigned, line %d\n",
' 517 name, subNum, line_num);
' 518 return;
' 519 }
' 520
' 521 cp->mon_flag_list[subNum] = TRUE;
' 522 return;
' 523 }
' 524
' 525 /* Parsing "sync" statement */
2010-03-01 ben.franksen 526 void sync_stmt(char *name, char *subscript, char *ef_name)
2000-04-04 William 527 {
03:23:15 ' 528 Chan *cp;
' 529 Var *vp;
' 530 extern int line_num;
' 531 int subNum;
' 532
' 533 #ifdef DEBUG
' 534 fprintf(stderr, "sync_stmt: name=%s, subNum=%s, ef_name=%s\n",
' 535 name, subscript?subscript:"(no subscript)", ef_name);
' 536 #endif /*DEBUG*/
' 537
' 538 vp = (Var *)findVar(name);
' 539 if (vp == 0)
' 540 {
' 541 fprintf(stderr, "sync: variable %s not declared, line %d\n",
' 542 name, line_num);
' 543 return;
' 544 }
' 545
' 546 cp = vp->chan;
' 547 if (cp == 0)
' 548 {
' 549 fprintf(stderr, "sync: variable %s not assigned, line %d\n",
' 550 name, line_num);
' 551 return;
' 552 }
' 553
' 554 /* Find the event flag varible */
' 555 vp = (Var *)findVar(ef_name);
' 556 if (vp == 0 || vp->type != V_EVFLAG)
' 557 {
' 558 fprintf(stderr, "sync: e-f variable %s not declared, line %d\n",
' 559 ef_name, line_num);
' 560 return;
' 561 }
' 562
' 563 if (subscript == NULL)
' 564 { /* no subscript */
' 565 if (cp->db_name != NULL)
' 566 { /* 1 pv assigned to this variable */
' 567 cp->ef_var = vp;
' 568 return;
' 569 }
' 570
' 571 /* 1 pv per element in the array */
' 572 for (subNum = 0; subNum < cp->num_elem; subNum++)
' 573 {
' 574 cp->ef_var_list[subNum] = vp;
' 575 }
' 576 return;
' 577 }
' 578
' 579 /* subscript != NULL */
' 580 subNum = atoi(subscript);
' 581 if (subNum < 0 || subNum >= cp->num_elem)
' 582 {
' 583 fprintf(stderr,
' 584 "sync: subscript %s[%d] out of range, line %d\n",
' 585 name, subNum, line_num);
' 586 return;
' 587 }
' 588 cp->ef_var_list[subNum] = vp; /* sync to a specific element of the array */
' 589
' 590 return;
' 591 }
' 592
' 593 /* Parsing "syncq" statement */
2010-03-01 ben.franksen 594 void syncq_stmt(char *name, char *subscript, char *ef_name, char *maxQueueSize)
2000-04-04 William 595 {
03:23:15 ' 596 Chan *cp;
' 597 Var *vp;
' 598 Var *efp;
' 599 extern int line_num;
' 600 int subNum;
' 601
' 602 #ifdef DEBUG
' 603 fprintf(stderr, "syncq_stmt: name=%s, subNum=%s, ef_name=%s, "
' 604 "maxQueueSize=%s\n", name, subscript, ef_name, maxQueueSize);
' 605 #endif /*DEBUG*/
' 606
' 607 /* Find the variable and check it's assigned */
' 608 vp = (Var *)findVar(name);
' 609 if (vp == 0)
' 610 {
' 611 fprintf(stderr, "syncQ: variable %s not declared, line %d\n",
' 612 name, line_num);
' 613 return;
' 614 }
' 615
' 616 cp = vp->chan;
' 617 if (cp == 0)
' 618 {
' 619 fprintf(stderr, "syncQ: variable %s not assigned, line %d\n",
' 620 name, line_num);
' 621 return;
' 622 }
' 623
' 624 /* Check that the variable has not already been syncQ'd */
' 625 if (vp->queued)
' 626 {
' 627 fprintf(stderr, "syncQ: variable %s already syncQ'd, "
' 628 "line %d\n", name, line_num);
' 629 return;
' 630 }
' 631
' 632 /* Find the event flag variable */
' 633 efp = (Var *)findVar(ef_name);
' 634 if (efp == 0 || efp->type != V_EVFLAG)
' 635 {
' 636 fprintf(stderr, "syncQ: e-f variable %s not declared, "
' 637 "line %d\n", ef_name, line_num);
' 638 return;
' 639 }
' 640
' 641 /* Check that the event flag has not already been syncQ'd */
' 642 if (efp->queued)
' 643 {
' 644 fprintf(stderr, "syncQ: e-f variable %s already syncQ'd, "
' 645 "line %d\n", ef_name, line_num);
' 646 return;
' 647 }
' 648
' 649 /* Note queued (for both variable and event flag) and set the
' 650 maximum queue size (0 means default) */
' 651 vp->queued = efp->queued = TRUE;
' 652 vp->maxQueueSize = (maxQueueSize == NULL) ? 0 : atoi(maxQueueSize);
' 653
' 654 if (subscript == NULL)
' 655 { /* no subscript */
' 656 if (cp->db_name != NULL)
' 657 { /* 1 pv assigned to this variable */
' 658 cp->ef_var = efp;
' 659 return;
' 660 }
' 661
' 662 /* 1 pv per element in the array */
' 663 for (subNum = 0; subNum < cp->num_elem; subNum++)
' 664 {
' 665 cp->ef_var_list[subNum] = efp;
' 666 }
' 667 return;
' 668 }
' 669
' 670 /* subscript != NULL */
' 671 subNum = atoi(subscript);
' 672 if (subNum < 0 || subNum >= cp->num_elem)
' 673 {
' 674 fprintf(stderr,
' 675 "syncQ: subscript %s[%d] out of range, line %d\n",
' 676 name, subNum, line_num);
' 677 return;
' 678 }
' 679 cp->ef_var_list[subNum] = efp; /* sync to a specific element of the array */
' 680
' 681 return;
' 682 }
' 683
' 684
' 685 /* Definition C code */
2010-03-01 ben.franksen 686 void defn_c_stmt(
21:37:20 ' 687 Expr *c_list /* ptr to C code */
' 688 )
2000-04-04 William 689 {
03:23:15 ' 690 #ifdef DEBUG
' 691 fprintf(stderr, "defn_c_stmt\n");
' 692 #endif /*DEBUG*/
' 693 if (defn_c_list == 0)
' 694 defn_c_list = c_list;
' 695 else
' 696 link_expr(defn_c_list, c_list);
' 697
' 698 return;
' 699 }
' 700
' 701 /* Global C code (follows state program) */
2010-03-01 ben.franksen 702 void global_c_stmt(
21:37:20 ' 703 Expr *c_list /* ptr to C code */
' 704 )
2000-04-04 William 705 {
03:23:15 ' 706 global_c_list = c_list;
' 707
' 708 return;
' 709 }
' 710
' 711
' 712 /* Add a variable to the variable linked list */
2010-03-01 ben.franksen 713 void addVar(Var *vp)
2000-04-04 William 714 {
03:23:15 ' 715 if (var_list == NULL)
' 716 var_list = vp;
' 717 else
' 718 var_tail->next = vp;
' 719 var_tail = vp;
' 720 vp->next = NULL;
' 721 }
' 722
' 723 /* Find a variable by name; returns a pointer to the Var struct;
' 724 returns 0 if the variable is not found. */
2010-03-01 ben.franksen 725 Var *findVar(char *name)
2000-04-04 William 726 {
03:23:15 ' 727 Var *vp;
' 728
' 729 for (vp = var_list; vp != NULL; vp = vp->next)
' 730 {
' 731 if (strcmp(vp->name, name) == 0)
' 732 {
' 733 return vp;
' 734 }
' 735 }
' 736 return 0;
' 737 }
' 738
' 739 /* Add a channel to the channel linked list */
2010-03-01 ben.franksen 740 void addChan(Chan *cp)
2000-04-04 William 741 {
03:23:15 ' 742 if (chan_list == NULL)
' 743 chan_list = cp;
' 744 else
' 745 chan_tail->next = cp;
' 746 chan_tail = cp;
' 747 cp->next = NULL;
' 748 }
' 749
' 750 /* Set debug print opt */
2010-03-01 ben.franksen 751 void set_debug_print(char *opt)
2000-04-04 William 752 {
03:23:15 ' 753 debug_print_opt = atoi(opt);
' 754 }
' 755
' 756 /* Parsing "program" statement */
2010-03-01 ben.franksen 757 void program(Expr *prog_list)
2000-04-04 William 758 {
03:23:15 ' 759 ss_list = prog_list;
' 760 #ifdef DEBUG
' 761 fprintf(stderr, "----Phase2---\n");
' 762 #endif /*DEBUG*/
' 763 phase2();
' 764
' 765 exit(0);
' 766 }
' 767
' 768 /* Entry code */
2010-03-01 ben.franksen 769 int entry_code(Expr *ep)
2000-04-04 William 770 {
03:23:15 ' 771 entry_code_list = ep;
' 772 return 0;
' 773 }
' 774
' 775 /* Exit code */
2010-03-01 ben.franksen 776 int exit_code(Expr *ep)
2000-04-04 William 777 {
03:23:15 ' 778 exit_code_list = ep;
' 779 return 0;
' 780 }
' 781
' 782 /* Build an expression list (hierarchical):
' 783 Builds a node on a binary tree for each expression primitive.
' 784 */
2010-03-01 ben.franksen 785 Expr *expression(
21:37:20 ' 786 int type, /* E_BINOP, E_ASGNOP, etc */
' 787 char *value, /* "==", "+=", var name, constant, etc. */
' 788 Expr *left, /* LH side */
' 789 Expr *right /* RH side */
' 790 )
2000-04-04 William 791 {
03:23:15 ' 792 Expr *ep;
' 793 extern int line_num, c_line_num;
' 794 extern char *src_file;
' 795 #ifdef DEBUG
' 796 extern char *stype[];
' 797 #endif /*DEBUG*/
' 798 /* Allocate a structure for this item or expression */
' 799 ep = allocExpr();
' 800 #ifdef DEBUG
' 801 fprintf(stderr,
' 802 "expression: ep=%d, type=%s, value=\"%s\", left=%d, right=%d\n",
' 803 ep, stype[type], value, left, right);
' 804 #endif /*DEBUG*/
' 805 /* Fill in the structure */
' 806 ep->next = (Expr *)0;
' 807 ep->last = ep;
' 808 ep->type = type;
' 809 ep->value = value;
' 810 ep->left = left;
' 811 ep->right = right;
' 812 if (type == E_TEXT)
' 813 ep->line_num = c_line_num;
' 814 else
' 815 ep->line_num = line_num;
' 816 ep->src_file = src_file;
' 817
' 818 return ep;
' 819 }
' 820
' 821 /* Link two expression structures and/or lists. Returns ptr to combined list.
' 822 Note: ->last ptrs are correct only for 1-st and last structures in the list */
2010-03-01 ben.franksen 823 Expr *link_expr(
21:37:20 ' 824 Expr *ep1, /* beginning of 1-st structure or list */
' 825 Expr *ep2 /* beginning 2-nd (append it to 1-st) */
' 826 )
2000-04-04 William 827 {
03:23:15 ' 828 if (ep1 == 0 && ep2 == 0)
' 829 return NULL;
' 830 else if (ep1 == 0)
' 831 return ep2;
' 832 else if (ep2 == 0)
' 833 return ep1;
' 834
' 835 (ep1->last)->next = ep2;
' 836 ep1->last = ep2->last;
' 837 #ifdef DEBUG
' 838 fprintf(stderr, "link_expr(");
' 839 for (ep = ep1; ; ep = ep->next)
' 840 {
' 841 fprintf(stderr, "%d, ", ep);
' 842 if (ep == ep1->last)
' 843 break;
' 844 }
' 845 fprintf(stderr, ")\n");
' 846 #endif /*DEBUG*/
' 847 return ep1;
' 848 }
' 849
' 850 /* Interpret pre-processor code */
2010-03-01 ben.franksen 851 void pp_code(char *line, char *fname)
2000-04-04 William 852 {
03:23:15 ' 853 extern int line_num;
' 854 extern char *src_file;
' 855
' 856 line_num = atoi(line);
2004-11-10 Janet 857 if (fname != 0)
2000-04-04 William 858 src_file = fname;
03:23:15 ' 859 }
' 860
' 861 /* The ordering of this list must correspond with the ordering in parse.h */
' 862 char *stype[] = {
' 863 "E_EMPTY", "E_CONST", "E_VAR", "E_FUNC", "E_STRING", "E_UNOP", "E_BINOP",
' 864 "E_ASGNOP", "E_PAREN", "E_SUBSCR", "E_TEXT", "E_STMT", "E_CMPND",
' 865 "E_IF", "E_ELSE", "E_WHILE", "E_SS", "E_STATE", "E_WHEN",
' 866 "E_FOR", "E_X", "E_PRE", "E_POST", "E_BREAK", "E_COMMA", "E_DECL",
' 867 "E_ENTRY", "E_EXIT", "E_OPTION", "E_?", "E_?", "E_?", "E_?", "E_?" };