bool matchExpr(ACCExpr *lhs, ACCExpr *rhs) { if (!lhs && !rhs) return true; if (!lhs || !rhs || lhs->value != rhs->value || lhs->operands.size() != rhs->operands.size()) return false; if ((lhs->value == "&" || lhs->value == "|") && lhs->operands.size() == 2) // check commutativity if (matchExpr(getRHS(lhs), getRHS(rhs, 0)) && matchExpr(getRHS(lhs, 0), getRHS(rhs))) return true; for (auto lcur = lhs->operands.begin(), lend = lhs->operands.end(), rcur = rhs->operands.begin(); lcur != lend; lcur++, rcur++) if (!matchExpr(*lcur, *rcur)) return false; return true; }
ExprPtr Parser::patternMatch(bool se) { expect(TCase); auto const& value = primaryExpression(false); expect(TLBrace); IntrusiveRefCntPtr<MatchExpr> matchExpr(new MatchExpr(value)); do { if(token == TTypeIdent || token == TIdent) // TODO: firstPattern set { enterScope(new Scope); auto pt = pattern(false); // TODO: Allow pattern = expr auto body = exitScope<Expr>(block(true)); matchExpr->legs.push_back(MatchLeg(pt, body)); } } while(test(TSemicolon)); expect(TRBrace, se); return ExprPtr(matchExpr.getPtr()); // TEMP }
void walkReplaceBuiltin(ACCExpr *expr) { while(1) { if (expr->value == "__bitconcat") { ACCExpr *list = expr->operands.front(); if (list->value == PARAMETER_MARKER) list->value = "{"; expr->value = list->value; expr->operands = list->operands; } else if (expr->value == "__bitsubstr") { ACCExpr *list = expr->operands.front(); ACCExpr *bitem = list->operands.front(); if (!isIdChar(bitem->value[0])) { // can only do bit select on net or reg (not expressions) printf("[%s:%d] can only do __bitsubstr on elementary items\n", __FUNCTION__, __LINE__); dumpExpr("BITSUB", expr); exit(-1); } bitem->operands.push_back(allocExpr("[", allocExpr(":", getRHS(list), getRHS(list, 2)))); expr->value = bitem->value; expr->operands = bitem->operands; } else if (expr->value == "__phi") { ACCExpr *list = expr->operands.front(); // get "(" list of [":", cond, value] items int size = list->operands.size(); ACCExpr *firstInList = getRHS(list, 0), *secondInList = getRHS(list); ACCExpr *newe = nullptr; if (size == 2 && matchExpr(getRHS(firstInList, 0), invertExpr(getRHS(secondInList, 0)))) newe = allocExpr("?", getRHS(firstInList, 0), getRHS(firstInList), getRHS(secondInList)); else if (size == 2 && getRHS(firstInList, 0)->value == "__default" && exprWidth(getRHS(secondInList)) == 1) newe = allocExpr("&", getRHS(secondInList, 0), getRHS(secondInList)); else if (size == 1) newe = getRHS(firstInList); else { //dumpExpr("PHI", list); newe = allocExpr("|"); for (auto item: list->operands) { dumpExpr("PHIELEMENTBEF", item); if (checkInteger(getRHS(item), "0")) continue; // default value is already '0' item->value = "?"; // Change from ':' -> '?' item->operands.push_back(allocExpr("0")); updateWidth(item, exprWidth(getRHS(item))); newe->operands.push_back(item); if (trace_expr) dumpExpr("PHIELEMENT", item); } } expr->value = newe->value; expr->operands = newe->operands; } else break; } for (auto item: expr->operands) walkReplaceBuiltin(item); }