*** 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)
{