*** 1.1 1995/01/17 18:48:49 --- token.h 1995/02/02 03:26:39 *************** *** 121,130 **** yy(0, 97, 0, 0, 0, 0, 0) yy(0, 98, 0, 0, 0, 0, 0) yy(0, 99, 0, 0, 0, 0, 0) ! yy(0, 100, 0, 0, 0, 0, 0) ! yy(0, 101, 0, 0, 0, 0, 0) ! yy(0, 102, 0, 0, 0, 0, 0) ! yy(0, 103, 0, 0, 0, 0, 0) yy(0, 104, 0, 0, 0, 0, 0) yy(0, 105, 0, 0, 0, 0, 0) yy(0, 106, 0, 0, 0, 0, 0) --- 121,130 ---- yy(0, 97, 0, 0, 0, 0, 0) yy(0, 98, 0, 0, 0, 0, 0) yy(0, 99, 0, 0, 0, 0, 0) ! zz(QINT, 100, 0, 0, 0, CHAR, "qint") ! zz(QIF, 101, 0, 0, 0, IF, "qif") ! zz(QELSE, 102, 0, 0, 0, IF, "qelse") ! zz(QINFLUENCE, 103, 0, 0, 0, IF, "qinfluence") yy(0, 104, 0, 0, 0, 0, 0) yy(0, 105, 0, 0, 0, 0, 0) yy(0, 106, 0, 0, 0, 0, 0)
*** 1.1 1995/01/17 18:48:49 --- keywords.h 1995/02/02 03:26:40 *************** *** 166,171 **** --- 166,208 ---- return LONG; } goto id; + case 'q': + if (rcp[0] == 'e' + && rcp[1] == 'l' + && rcp[2] == 's' + && rcp[3] == 'e' + && !(map[rcp[4]]&(DIGIT|LETTER))) { + cp = rcp + 4; + return QELSE; + } + if (rcp[0] == 'i' + && rcp[1] == 'f' + && !(map[rcp[2]]&(DIGIT|LETTER))) { + cp = rcp + 2; + return QIF; + } + if (rcp[0] == 'i' + && rcp[1] == 'n' + && rcp[2] == 'f' + && rcp[3] == 'l' + && rcp[4] == 'u' + && rcp[5] == 'e' + && rcp[6] == 'n' + && rcp[7] == 'c' + && rcp[8] == 'e' + && !(map[rcp[9]]&(DIGIT|LETTER))) { + cp = rcp + 9; + return QINFLUENCE; + } + if (rcp[0] == 'i' + && rcp[1] == 'n' + && rcp[2] == 't' + && !(map[rcp[3]]&(DIGIT|LETTER))) { + cp = rcp + 3; + tsym = inttype_sym; + return QINT; + } + goto id; case 'r': if (rcp[0] == 'e' && rcp[1] == 'g' *************** *** 314,320 **** case 'n': case 'o': case 'p': - case 'q': case 'x': case 'y': case 'z': --- 351,356 ----
*** 1.1 1995/01/17 18:48:49 --- stmt.cc 1995/02/03 02:34:01 *************** *** 43,48 **** --- 43,52 ---- var_sym *for_index, operand *for_ub); static void ifstmt(label_sym *continue_lab, label_sym *break_lab, struct swtch *swp, int lev); + static void qifstmt(label_sym *continue_lab, label_sym *break_lab, + struct swtch *swp, int lev); + static void qinfluencestmt(label_sym *continue_lab, label_sym *break_lab, + struct swtch *swp, int lev); static var_sym *localaddr(genop p); static void return_void(void); static void return_value(genop to_return); *************** *** 53,58 **** --- 57,64 ---- static void swstmt(label_sym *continue_lab, int lev); static void whilestmt(struct swtch *swp, int lev); + extern char *k_qif_statement; + extern char *k_qinfluence; /* branch - jump to lab */ static void branch(label_sym *target) *************** *** 879,888 **** --- 885,1032 ---- statement(continue_lab, break_lab, swp, lev); } + if (t == QELSE) + { + static char follow[] = { IF, ID, '}', 0 }; + error("[PSH] if followed by a qelse, skipping.\n"); + skipto(0, follow); + } + + curr_list = old_list; + + } + + int currently_parsing_qif_expression = 0; + /* flag: when set, the expression parsing code doesn't consider + use of an undeclared identifier (i.e., the qif variable) an error. */ + char qif_buffer[1024]; + /* storage buffer: if there are a set of parentheses after the qif + keyword, what they enclose is stored here for the annotation. */ + + /* qifstmt - qif ( expression ) statement [ qelse qifstmt|statement ] */ + static void qifstmt(label_sym *continue_lab, label_sym *break_lab, + struct swtch *swp, int lev) + { + { + int status; + + qif_buffer[0] = (char) 0; + status = sscanf(cp, " (%[^)])", qif_buffer); + if ((strlen(qif_buffer) == 0) || (status != 1)) + warning("[PSH] Couldn't find '(...)' after a qif.\n"); + } + + t = gettok(); + expect('('); + definept(NULL); + + currently_parsing_qif_expression++; + genop e = conditional(')'); + currently_parsing_qif_expression--; + e.clean_up_bit_field_refs(); + + label_sym *else_label = genlabel(); + tree_node_list *if_test = e.precomputation(); + operand test_operand = e.suif_operand(); + instruction *branch_instr = new in_bj(io_bfalse, else_label, test_operand); + if_test->append(new tree_instr(branch_instr)); + + tree_node_list *then_part = new tree_node_list; + tree_node_list *else_part = new tree_node_list; + tree_if *the_if = new tree_if(else_label, if_test, then_part, else_part); + assert(curr_list != NULL); + curr_list->append(the_if); + + { + immed *i = new immed(qif_buffer); + immed_list_e *ile = new immed_list_e(*i); + immed_list *il = new immed_list(); + il->push(ile); + + the_if.append_annote(k_qif_statement, (void *) il); + } + + tree_node_list *old_list = curr_list; + curr_list = then_part; + refinc /= 2; + if (refinc == 0) + refinc = 1; + statement(continue_lab, break_lab, swp, lev); + + if (t == QELSE) + { + curr_list = else_part; + t = gettok(); + statement(continue_lab, break_lab, swp, lev); + } + + if (t == ELSE) + { + static char follow[] = { IF, ID, '}', 0 }; + error("[PSH] qif followed by a else, skipping.\n"); + skipto(0, follow); + } + curr_list = old_list; } + tree_block *qinfluence_block = NULL; + /* At outermost scope so that stabblock() can modify it; the + use of previous_qinfluence_block inside qinfluencestmt() is + intended to store values of qinfluence_block in stack variables + for nested qinfluences. */ + int just_parsed_qinfluence_statement = 0; + + /* qinfluencestmt - qinfluence ( expression ) statement */ + static void qinfluencestmt(label_sym *continue_lab, label_sym *break_lab, + struct swtch *swp, int lev) + { + char qinfluence_buffer[1024]; + /* storage buffer: if there are a set of parentheses after the qinfluence + keyword, what they enclose is stored here for the annotation. */ + tree_block *previous_qinfluence_block; + + previous_qinfluence_block = qinfluence_block; + + { + int status; + + qinfluence_buffer[0] = (char) 0; + status = sscanf(cp, " (%[^)])", qinfluence_buffer); + if ((strlen(qinfluence_buffer) == 0) || (status != 1)) + warning("[PSH] Couldn't find '(...)' after a qinfluence.\n"); + } + + t = gettok(); + expect('('); + definept(NULL); + + /* I don't need to set a flag while parsing the contents of '(...)' + since it *IS* an error if there is a qinfluence variable which + hasn't already been introduced by a qint. */ + genop e = conditional(')'); + e.clean_up_bit_field_refs(); + + refinc /= 2; + if (refinc == 0) + refinc = 1; + just_parsed_qinfluence_statement++; + /* stabblock() will do the just_parsed_qinfluence_statement-- */ + statement(continue_lab, break_lab, swp, lev); + + { + immed *i = new immed(qinfluence_buffer); + immed_list_e *ile = new immed_list_e(*i); + immed_list *il = new immed_list(); + il->push(ile); + + qinfluence_block->append_annote(k_qinfluence, (void *) il); + } + + qinfluence_block = previous_qinfluence_block; + } + /* localaddr - returns q if p yields the address of local/parameter q; otherwise returns NULL */ static var_sym *localaddr(genop p) *************** *** 1007,1012 **** --- 1151,1162 ---- case IF: ifstmt(continue_lab, break_lab, swp, lev + 1); break; + case QIF: + qifstmt(continue_lab, break_lab, swp, lev + 1); + break; + case QINFLUENCE: + qinfluencestmt(continue_lab, break_lab, swp, lev + 1); + break; case WHILE: whilestmt(swp, lev + 1); break;
*** 1.1 1995/01/18 19:11:03 --- expr.cc 1995/05/21 01:23:52 *************** *** 1172,1177 **** --- 1172,1180 ---- return genop(operand(), new tree_node_list); } + extern int currently_parsing_qif_expression; + extern char *k_qif_variable; + /* primary - parse a primary expression */ static genop primary(void) { *************** *** 1209,1220 **** } else { ! error("undeclared identifier `%s'\n", q->name); ! q->sclass = AUTO; ! q->type = inttype; ! q->suif_symbol = ! get_current_symtab()->new_var(q->type, q->name); ! q->suif_symbol->set_userdef(); } if (xref) use(q, src); --- 1212,1244 ---- } else { ! if (currently_parsing_qif_expression) ! { ! base_symtab *global_st; ! global_st = get_current_symtab(); ! while (global_st->kind() != SYMTAB_GLOBAL) ! global_st = global_st->parent(); ! ! q->sclass = EXTERN; ! q->type = qual(CONST, inttype); ! if ((q->suif_symbol = global_st->lookup_var(q->name)) ! == NULL) ! { ! q->suif_symbol = ! global_st->new_var(q->type, q->name); ! q->suif_symbol->set_userdef(); ! q->suif_symbol->append_annote(k_qif_variable); ! } ! } ! else ! { ! error("undeclared identifier `%s'\n", q->name); ! q->sclass = AUTO; ! q->type = inttype; ! q->suif_symbol = ! get_current_symtab()->new_var(q->type, q->name); ! q->suif_symbol->set_userdef(); ! } } if (xref) use(q, src);
*** 1.1 1995/01/18 20:10:47 --- decl.cc 1995/04/14 15:08:31 *************** *** 44,49 **** --- 44,57 ---- static type_node *parse_type(int lev, int *sclass); static boolean control_reaches_list_end(tree_node_list *node_list); + extern char *k_qint_parameter; + int just_parsed_qint_type = 0; + /* flag: when set, the symbol of the declaration being parsed + will be annotated with qint_parameter. */ + char qint_buffer[1024]; + /* storage buffer: if there are a set of brackets following the + qint keyword, what they enclose is stored here for the annotation. */ + /* checklab - check for undefined labels; called at ends of functions */ static void checklab(Symbol p, Generic cl) { *************** *** 648,653 **** --- 656,668 ---- pt = src; type_node *ty = parse_type(level, &sclass); + + if ((just_parsed_qint_type) && (t != ID)) + { + warning("[PSH] qint not followed by identifier, faking int.\n"); + just_parsed_qint_type--; + } + if ((t == ID) || (t == '*') || (t == '(') || (t == '[')) { Coordinate pos; *************** *** 690,696 **** else if (sclass == TYPEDEF) (void)deftype(id, ty1, &pos); else ! (*dcl)(sclass, id, ty1, &pos); if (t != ',') break; t = gettok(); --- 705,728 ---- else if (sclass == TYPEDEF) (void)deftype(id, ty1, &pos); else ! { ! if (just_parsed_qint_type) ! { ! Symbol p = dclglobal(sclass, id, qual(CONST,ty1), &pos); ! ! immed *i = new immed(qint_buffer); ! immed_list_e *ile = new immed_list_e(*i); ! immed_list *il = new immed_list(); ! il->push(ile); ! ! assert(p->suif_symbol != NULL); ! p->suif_symbol->append_annote(k_qint_parameter, ! (void *) il); ! just_parsed_qint_type--; ! } ! else ! (*dcl)(sclass, id, ty1, &pos); ! } if (t != ',') break; t = gettok(); *************** *** 903,908 **** --- 935,947 ---- { static char follow[] = { IF, CHAR, '}', 0 }; type_node *ty1 = parse_type(0, NULL); + + if (just_parsed_qint_type) + { + warning("[PSH] qint type while parsing fields, faking int.\n"); + just_parsed_qint_type--; + } + do { char *id = NULL; *************** *** 1434,1439 **** --- 1473,1486 ---- error("missing parameter type\n"); } ty = dclr(parse_type(PARAM, &sclass), &id, lev + 1); + + if (just_parsed_qint_type) + { + warning("[PSH] qint type while parsing parameters, " + "faking int.\n"); + just_parsed_qint_type--; + } + if ((Aflag >= 1) && !hasproto(ty)) warning("missing prototype\n"); if ((ty == voidtype) && ((last != NULL) || (id != NULL))) *************** *** 1625,1630 **** --- 1672,1695 ---- case SHORT: p = &size; break; + case QINT: + { + int status; + + qint_buffer[0] = (char) 0; + status = sscanf(cp, " [%[^]]]", qint_buffer); + if ((strlen(qint_buffer) == 0) || (status != 1)) + warning("[PSH] Couldn't find '[...]' after a qint.\n"); + else + { + just_parsed_qint_type++; + while (*cp != '[') cp++; + cp++; + while (*cp != ']') cp++; + cp++; + } + } + /* deliberately falling through */ case VOID: case CHAR: case INT:
*** 1.1 1995/02/02 20:31:55 --- gen.cc 1995/05/03 16:41:21 *************** *** 36,42 **** #include "c.h" RCS_BASE( ! "$Id: gen.cc,v 1.1 1995/02/02 20:31:55 pshuang Exp $") --- 36,42 ---- #include "c.h" RCS_BASE( ! "$Id: gen.cc,v 1.3 1995/05/03 16:41:17 pshuang Exp pshuang $") *************** *** 278,283 **** --- 278,285 ---- * BEGINNING/END OF BLOCK FUNCTIONS * ********************************************************************/ + extern tree_block *qinfluence_block; + extern int just_parsed_qinfluence_statement; // enter/exit a block in the emit phase, with its user-defined locals void stabblock(int enter_or_exit, int level) *************** *** 301,306 **** --- 303,321 ---- tree_block *b = new tree_block(new_list, new_symtab); curr_list->append(b); + + if (just_parsed_qinfluence_statement) + { + just_parsed_qinfluence_statement--; + qinfluence_block = b; + new_symtab->new_var(qual(CONST,inttype), + "QINFLUENCE_BLOCK_HOLDER"); + /* Entering this dummy variable prevents SUIF from optimizing + the block away; otherwise, a qinfluence() whose body + does not introduce any scope variables will be reduced + to the statements in the body, and the annotation + I attach to the block will vanish. */ + } curr_list = new_list; if (curr_symtab != NULL)
*** 1.1 1995/01/17 22:19:42 --- main.cc 1995/02/19 22:20:06 *************** *** 13,18 **** --- 13,23 ---- #include "c.h" + char *k_qif_statement; /* annotation for the qif statement itself */ + char *k_qif_variable; /* annotation for quasistatic variables */ + char *k_qint_parameter; /* annotation for quasistatic parameters */ + char *k_qinfluence; /* annotation for quasistatic parameters */ + int Aflag; /* > 0 if -W specified */ boolean Pflag; /* TRUE if -P specified */ boolean xref; /* TRUE for cross-reference data */ *************** *** 40,45 **** --- 45,55 ---- init_bit_ref(); level = GLOBAL; assert(inttype->size() >= voidptype->size()); + + ANNOTE(k_qif_statement, "QIF STATEMENT", TRUE); + ANNOTE(k_qif_variable, "QIF VARIABLE", TRUE); + ANNOTE(k_qint_parameter, "QINT PARAMETER", TRUE); + ANNOTE(k_qinfluence, "QINFLUENCE STATEMENT", TRUE); if (option_null_check) {