|
|
|
@ -569,11 +569,22 @@ static void move_inputs(struct gate_data *curr, struct gate_data *prev) |
|
|
|
prev->finished = TRUE; |
|
|
|
} |
|
|
|
|
|
|
|
static void scan_gates(DSTRING *lhs) |
|
|
|
static void scan_gates(DSTRING *lhs, int optimize) |
|
|
|
{ |
|
|
|
struct gate_data *current = NULL, *previous = NULL, *last_curr = NULL; |
|
|
|
struct gate_data *prev = NULL; |
|
|
|
|
|
|
|
if (optimize < 1) { |
|
|
|
current = last_gate; |
|
|
|
if (ds_get_length(lhs) > 0) { |
|
|
|
assert(current->finished == FALSE); |
|
|
|
tfree(current->outp); |
|
|
|
current->outp = TMALLOC(char, ds_get_length(lhs) + 1); |
|
|
|
strcpy(current->outp, ds_get_buf(lhs)); |
|
|
|
} |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
current = first_gate; |
|
|
|
while (current) { |
|
|
|
int is_gate = (current->type == '&' |
|
|
|
@ -581,7 +592,8 @@ static void scan_gates(DSTRING *lhs) |
|
|
|
|| current->type == '|'); |
|
|
|
previous = current->prev; |
|
|
|
if (is_gate && current->is_possible) { |
|
|
|
if (previous && previous->type == current->type) { |
|
|
|
if (previous && previous->type == current->type |
|
|
|
&& previous->is_not == current->is_not) { |
|
|
|
if (eq(current->ins->name, previous->outp)) { |
|
|
|
move_inputs(current, previous); |
|
|
|
} |
|
|
|
@ -608,6 +620,7 @@ static void scan_gates(DSTRING *lhs) |
|
|
|
prev = current->prev; |
|
|
|
while (prev) { |
|
|
|
if (prev->type == current->type |
|
|
|
&& prev->is_not == current->is_not |
|
|
|
&& prev->finished == FALSE |
|
|
|
&& strncmp(prev->outp, TMP_PREFIX, TMP_LEN) == 0 |
|
|
|
&& eq(current->ins->name, prev->outp)) { |
|
|
|
@ -748,36 +761,44 @@ static int infix_to_postfix(char* infix, DSTRING * postfix_p) |
|
|
|
nlist = add_name_entry("first", NULL); |
|
|
|
ds_clear(postfix_p); |
|
|
|
while ( ( ltok = lexer_scan(lx) ) != 0 ) { // start while ltok loop |
|
|
|
if (ltok == LEX_ID && last_tok == LEX_ID) { |
|
|
|
fprintf(stderr, "ERROR (1) no gate operator between two identifiers\n"); |
|
|
|
status = 1; |
|
|
|
goto err_return; |
|
|
|
} |
|
|
|
if (lex_gate_op(ltok)) { |
|
|
|
if (lex_gate_op(last_tok)) { |
|
|
|
fprintf(stderr, "ERROR (2) two consecutive gate operators\n"); |
|
|
|
status = 1; |
|
|
|
goto err_return; |
|
|
|
} else if (last_tok != LEX_ID && last_tok != ')') { |
|
|
|
fprintf(stderr, "ERROR (2a) gate operator not after ID or rparen\n"); |
|
|
|
if (last_tok == -1) { // check starting token |
|
|
|
if (!(ltok == LEX_ID || ltok == '~' || ltok == '(')) { |
|
|
|
fprintf(stderr, "ERROR (1) invalid starting token\n"); |
|
|
|
status = 1; |
|
|
|
goto err_return; |
|
|
|
} |
|
|
|
} |
|
|
|
if (last_tok == '~' && ltok != LEX_ID && ltok != '(') { |
|
|
|
fprintf(stderr, "ERROR (3) \'~\' is not followed by an ID or lparen\n"); |
|
|
|
status = 1; |
|
|
|
goto err_return; |
|
|
|
} |
|
|
|
if (ltok == '~' && (last_tok == LEX_ID || last_tok == ')')) { |
|
|
|
fprintf(stderr, "ERROR (4) \'~\' follows an ID or rparen\n"); |
|
|
|
status = 1; |
|
|
|
goto err_return; |
|
|
|
} |
|
|
|
if (ltok == ')' && (lex_gate_op(last_tok) || last_tok == '~')) { |
|
|
|
fprintf(stderr, "ERROR (5) incomplete infix sub-expression\n"); |
|
|
|
status = 1; |
|
|
|
goto err_return; |
|
|
|
} else { |
|
|
|
if (last_tok == LEX_ID) { // check follower of an ID |
|
|
|
if (!(lex_gate_op(ltok) || ltok == ')')) { |
|
|
|
fprintf(stderr, "ERROR (2) incorrect token after ID\n"); |
|
|
|
status = 1; |
|
|
|
goto err_return; |
|
|
|
} |
|
|
|
} else if (lex_gate_op(last_tok)) { // check follower of a gate op |
|
|
|
if (!(ltok == LEX_ID || ltok == '~' || ltok == '(')) { |
|
|
|
fprintf(stderr, "ERROR (3) incorrect token after gate op\n"); |
|
|
|
status = 1; |
|
|
|
goto err_return; |
|
|
|
} |
|
|
|
} else if (last_tok == '~') { // check follower of ~ |
|
|
|
if (!(ltok == LEX_ID || ltok == '(')) { |
|
|
|
fprintf(stderr, "ERROR (4) incorrect token after \'~\'\n"); |
|
|
|
status = 1; |
|
|
|
goto err_return; |
|
|
|
} |
|
|
|
} else if (last_tok == '(') { // check follower of lparen |
|
|
|
if (!(ltok == LEX_ID || ltok == '~' || ltok == '(')) { |
|
|
|
fprintf(stderr, "ERROR (5) incorrect token after lparen\n"); |
|
|
|
status = 1; |
|
|
|
goto err_return; |
|
|
|
} |
|
|
|
} else if (last_tok == ')') { // check follower of rparen |
|
|
|
if (!(ltok == ')' || lex_gate_op(ltok))) { |
|
|
|
fprintf(stderr, "ERROR (6) incorrect token after rparen\n"); |
|
|
|
status = 1; |
|
|
|
goto err_return; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
last_tok = ltok; |
|
|
|
@ -797,6 +818,11 @@ static int infix_to_postfix(char* infix, DSTRING * postfix_p) |
|
|
|
} |
|
|
|
} else if (ltok == ')') { |
|
|
|
rparen_count++; |
|
|
|
if (rparen_count > lparen_count) { |
|
|
|
fprintf(stderr, "ERROR (9a) mismatched rparen\n"); |
|
|
|
status = 1; |
|
|
|
goto err_return; |
|
|
|
} |
|
|
|
while ( stack.top != -1 && !eq(stack.array[stack.top], "(") ) { |
|
|
|
ds_cat_printf(postfix_p, " %s", pop(&stack, &status)); |
|
|
|
if (status) { |
|
|
|
@ -832,19 +858,19 @@ static int infix_to_postfix(char* infix, DSTRING * postfix_p) |
|
|
|
goto err_return; |
|
|
|
} |
|
|
|
} else { |
|
|
|
fprintf(stderr, "ERROR (6) unexpected infix token %d \'%s\'\n", |
|
|
|
fprintf(stderr, "ERROR (7) unexpected infix token %d \'%s\'\n", |
|
|
|
ltok, lx->lexer_buf); |
|
|
|
status = 1; |
|
|
|
goto err_return; |
|
|
|
} |
|
|
|
} // end while ltok loop |
|
|
|
if (lex_gate_op(last_tok) || last_tok == '~') { |
|
|
|
fprintf(stderr, "ERROR (7) incomplete infix expression\n"); |
|
|
|
fprintf(stderr, "ERROR (8) incomplete infix expression\n"); |
|
|
|
status = 1; |
|
|
|
goto err_return; |
|
|
|
} |
|
|
|
if (lparen_count != rparen_count) { |
|
|
|
fprintf(stderr, "ERROR (8) mismatched parentheses\n"); |
|
|
|
fprintf(stderr, "ERROR (9) mismatched parentheses\n"); |
|
|
|
status = 1; |
|
|
|
goto err_return; |
|
|
|
} |
|
|
|
@ -966,7 +992,7 @@ err_return: |
|
|
|
/* Start of logicexp parser */ |
|
|
|
static void aerror(char *s); |
|
|
|
static BOOL amatch(int t); |
|
|
|
static BOOL bparse(char *line, BOOL new_lexer); |
|
|
|
static BOOL bparse(char *line, BOOL new_lexer, int optimize); |
|
|
|
|
|
|
|
static int lookahead = 0; |
|
|
|
static int number_of_instances = 0; |
|
|
|
@ -1061,7 +1087,7 @@ static BOOL amatch(int t) |
|
|
|
return TRUE; |
|
|
|
} |
|
|
|
|
|
|
|
static BOOL bstmt_postfix(void) |
|
|
|
static BOOL bstmt_postfix(int optimize) |
|
|
|
{ |
|
|
|
/* A stmt is: output_name_id = '{' expr '}' */ |
|
|
|
DS_CREATE(lhs, 32); |
|
|
|
@ -1113,7 +1139,7 @@ static BOOL bstmt_postfix(void) |
|
|
|
retval = FALSE; |
|
|
|
goto bail_out; |
|
|
|
} |
|
|
|
scan_gates(&lhs); |
|
|
|
scan_gates(&lhs, optimize); |
|
|
|
gen_scanned_gates(first_gate); |
|
|
|
lookahead = lex_scan(); |
|
|
|
while (lookahead != '}') { |
|
|
|
@ -1156,7 +1182,7 @@ static char *get_logicexp_tmodel_delays( |
|
|
|
return ds_get_buf(mname); |
|
|
|
} |
|
|
|
|
|
|
|
static BOOL bparse(char *line, BOOL new_lexer) |
|
|
|
static BOOL bparse(char *line, BOOL new_lexer, int optimize) |
|
|
|
{ |
|
|
|
BOOL ret_val = TRUE; |
|
|
|
DS_CREATE(stmt, LEX_BUF_SZ); |
|
|
|
@ -1171,7 +1197,7 @@ static BOOL bparse(char *line, BOOL new_lexer) |
|
|
|
while (lookahead != '\0') { |
|
|
|
ds_clear(&stmt); |
|
|
|
ds_cat_str(&stmt, parse_lexer->lexer_buf); |
|
|
|
if (!bstmt_postfix()) { |
|
|
|
if (!bstmt_postfix(optimize)) { |
|
|
|
cleanup_parser(); |
|
|
|
ret_val= FALSE; |
|
|
|
break; |
|
|
|
@ -1233,8 +1259,9 @@ static BOOL expect_token( |
|
|
|
return TRUE; |
|
|
|
} |
|
|
|
|
|
|
|
BOOL f_logicexp(char *line) |
|
|
|
BOOL f_logicexp(char *line, int optimize) |
|
|
|
{ |
|
|
|
/* If optimize > 0 then perform optimizations in scan_gates */ |
|
|
|
int t, num_ins = 0, num_outs = 0, i; |
|
|
|
char *endp; |
|
|
|
BOOL ret_val = TRUE; |
|
|
|
@ -1319,7 +1346,7 @@ BOOL f_logicexp(char *line) |
|
|
|
} |
|
|
|
(void) add_sym_tab_entry(parse_lexer->lexer_buf, |
|
|
|
SYM_TMODEL, &parse_lexer->lexer_sym_tab); |
|
|
|
ret_val = bparse(line, FALSE); |
|
|
|
ret_val = bparse(line, FALSE, optimize); |
|
|
|
|
|
|
|
current_lexer = NULL; |
|
|
|
if (!ret_val) { |
|
|
|
|