コード例 #1
0
ファイル: expr.cpp プロジェクト: cambridgehackers/atomicc
ACCExpr *cleanupExpr(ACCExpr *expr, bool preserveParen)
{
    if (!expr)
        return expr;
static int level;
    level++;
    if (expr->operands.size() == 1 && expr->operands.front()->value != "," && (!preserveParen && expr->value == "("))
        expr = expr->operands.front();
    if (isParen(expr->value) && expr->operands.size() == 1 && expr->operands.front()->value == ",")
        expr->operands = expr->operands.front()->operands;
    ACCExpr *ret = allocExpr(expr->value);
    bool booleanCond = expr->value == "?";
    for (auto item: expr->operands) {
         if (booleanCond)
             item = cleanupBool(item);
         ACCExpr *titem = cleanupExpr(item, isIdChar(expr->value[0]));
         booleanCond = false;
         if (titem->value != ret->value || ret->value == "?" || isParen(ret->value)
            || (  titem->value != "&" && titem->value != "|"
               && titem->value != "&&" && titem->value != "||"
               && titem->value != "+" && titem->value != "*"))
             ret->operands.push_back(titem);
         else {
             for (auto oitem: titem->operands)
                 ret->operands.push_back(oitem);
         }
    }
    level--;
    return ret;
}
コード例 #2
0
ファイル: expr.cpp プロジェクト: cambridgehackers/atomicc
std::string tree2str(ACCExpr *expr)
{
    if (!expr)
        return "";
    std::string ret, sep, op = expr->value;
    if (isParen(op)) {
        ret += op;
        if (expr->operands.size())
            ret += " ";
        op = ",";
    }
    else if (isIdChar(op[0])) {
        ret += op;
    }
    else if (!expr->operands.size() || ((op == "-" || op == "!")/*unary*/ && expr->operands.size() == 1))
        ret += op;
    bool topOp = checkOperand(expr->value) || expr->value == "," || expr->value == "[" || expr->value == PARAMETER_MARKER;
    for (auto item: expr->operands) {
        ret += sep;
        bool addParen = !topOp && !checkOperand(item->value) && item->value != ",";
        if (addParen)
            ret += "( ";
        ret += tree2str(item);
        if (addParen)
            ret += " )";
        sep = " " + op + " ";
        if (op == "?")
            op = ":";
    }
    ret += treePost(expr);
    return ret;
}
コード例 #3
0
ファイル: expr.cpp プロジェクト: cambridgehackers/atomicc
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);
}
コード例 #4
0
bool String::isIdentifier (String str)
{
  if (_len (str.buf) == 0)
    return false;
  if (!isIdStart (str.buf[0]))
    return false;
  for (int i = 1; i < _len (str.buf); i++)
    if (!isIdChar (str.buf[i]))
      return false;
  return true;
}
コード例 #5
0
ファイル: expr.cpp プロジェクト: cambridgehackers/atomicc
int exprWidth(ACCExpr *expr, bool forceNumeric)
{
    if (!expr)
        return 0;
    std::string op = expr->value;
    if (relationalOp(op))
        return 1;
    if (isdigit(op[0])) {
        int ind = op.find("'");
        if (ind > 0) {
            std::string temp = op.substr(0, ind);
            return atoi(temp.c_str());
        }
        else if (forceNumeric)
            return 1;
    }
    if (isIdChar(op[0])) {
        ACCExpr *lhs = getRHS(expr, 0);
        if (lhs && lhs->value == "[" && lhs->operands.size() > 0) {
            ACCExpr *first = getRHS(lhs, 0);
            if (first->value == ":") {
                ACCExpr *second = getRHS(first);
                first = getRHS(first, 0);
                if (!second)
                    return 1;
                if (isdigit(first->value[0]) && isdigit(second->value[0]))
                    return atoi(first->value.c_str()) - atoi(second->value.c_str()) + 1;
            }
            else if (isdigit(first->value[0]))
                return 1;
        }
        return convertType(refList[op].type);
    }
    if (op == "?") {
        if (int len = exprWidth(getRHS(expr, 1), forceNumeric))
            return len;
        if (int len = exprWidth(getRHS(expr, 2), forceNumeric))
            return len;
    }
    if (op == "&" || op == "|" || op == "^") {
        for (auto item: expr->operands)
            if (exprWidth(item, forceNumeric) != 1)
                goto nextand;
        return 1;
nextand:;
    }
    if (op == "!") {
        return exprWidth(expr->operands.front(), forceNumeric);
    }
    return 0;
}
コード例 #6
0
ファイル: lexer.cpp プロジェクト: cwz920716/butterfly
token_type getIdToken(const char *text, int *len) {
  int n = 0;
  if (isIdChar0(text[0])) {
    do {
      n++;
    } while (isIdChar(text[n]));
  }

  if (n == 0) return tok_error;

  *len = n;
  if (equalsKeyword(text, n, "define"))
    return tok_define;
  if (equalsKeyword(text, n, "lambda"))
    return tok_lambda;
  if (equalsKeyword(text, n, "if"))
    return tok_if;
  if (equalsKeyword(text, n, "cond"))
    return tok_cond;
  if (equalsKeyword(text, n, "begin"))
    return tok_begin;
  if (equalsKeyword(text, n, "and"))
    return tok_and;
  if (equalsKeyword(text, n, "or"))
    return tok_or;
  if (equalsKeyword(text, n, "not"))
    return tok_not;
  if (equalsKeyword(text, n, "box"))
    return tok_box;
  if (equalsKeyword(text, n, "unbox"))
    return tok_unbox;
  if (equalsKeyword(text, n, "setbox!"))
    return tok_setbox;
  if (equalsKeyword(text, n, "closure"))
    return tok_closure;
  if (equalsKeyword(text, n, "getfield"))
    return tok_getfield;
  if (equalsKeyword(text, n, "nil"))
    return tok_nil;
  if (equalsKeyword(text, n, "set!"))
    return tok_set;

  return tok_symbol;
}
コード例 #7
0
ファイル: expr.cpp プロジェクト: cambridgehackers/atomicc
void updateWidth(ACCExpr *expr, int len)
{
    int ilen = exprWidth(expr);
    if (ilen < 0 || len < 0) {
        printf("[%s:%d] len %d ilen %d tree %s\n", __FUNCTION__, __LINE__, len, ilen, tree2str(expr).c_str());
        exit(-1);
    }
    if (isdigit(expr->value[0]) && len > 0 && expr->value.find("'") == std::string::npos)
        expr->value = autostr(len) + "'d" + expr->value;
    else if (isIdChar(expr->value[0])) {
        if (trace_expr)
            printf("[%s:%d] ID %s ilen %d len %d\n", __FUNCTION__, __LINE__, tree2str(expr).c_str(), ilen, len);
        if (ilen > len && len > 0 && !expr->operands.size()) {
            ACCExpr *subexpr = allocExpr(":", allocExpr(autostr(len-1)));
            if (len > 1)
                subexpr->operands.push_back(allocExpr("0"));
            expr->operands.push_back(allocExpr("[", subexpr));
        }
    }
    else if (expr->value == ":") // for __phi
        updateWidth(getRHS(expr), len);
    else if (expr->value == "?") {
        updateWidth(getRHS(expr), len);
        updateWidth(getRHS(expr, 2), len);
    }
    else if (arithOp(expr->value) || expr->value == "(") {
        if (expr->value == "-" && expr->operands.size() == 1
            && isdigit(expr->operands.front()->value[0]) && len == 1) {
            /* hack to update width on "~foo", which translates to "foo ^ -1" in the IR */
            expr->value = expr->operands.front()->value;
            expr->operands.clear();
            updateWidth(expr, len);
        }
        else
        for (auto item: expr->operands)
            updateWidth(item, len);
    }
}
コード例 #8
0
bool String::isWordBoundary (int pos) const
{
  return pos <= 0 || pos >= _len (buf) || isIdChar (buf[pos]) != isIdChar (buf[pos - 1]);
}
コード例 #9
0
ファイル: expr.cpp プロジェクト: cambridgehackers/atomicc
bool checkOperand(std::string s)
{
    return isIdChar(s[0]) || isdigit(s[0]) || s == "(" || s == "{" || s[0] == '"';
}
コード例 #10
0
ファイル: expr.cpp プロジェクト: cambridgehackers/atomicc
static ACCExpr *getExprList(ACCExpr *head, std::string terminator, bool repeatCurrentToken, bool preserveParen)
{
    bool parseState = false;
    ACCExpr *currentOperand = nullptr;
    ACCExpr *tok;
    ACCExpr *exprStack[MAX_EXPR_DEPTH];
    int exprStackIndex = 0;
#define TOP exprStack[exprStackIndex]
    TOP = nullptr;
    if (trace_expr)
        printf("[%s:%d] head %s\n", __FUNCTION__, __LINE__, head ? head->value.c_str() : "(nil)");
    if (head) {
        while ((tok = get1Token()) && tok->value != terminator) {
            if (trace_expr)
                printf("[%s:%d] parseState %d tok->value %s repeat %d\n", __FUNCTION__, __LINE__, parseState, tok->value.c_str(), repeatCurrentToken);
            if ((parseState = !parseState)) {    /* Operand */
                ACCExpr *unary = nullptr;
                ACCExpr *tnext = tok;
                if (repeatCurrentToken)
                    tok = head;
                else
                    tnext = get1Token();
                repeatCurrentToken = false;
                if ((tok->value == "-" || tok->value == "!") && !tok->operands.size()) { // unary '-'
                    unary = tok;
                    tok = tnext;
                    tnext = get1Token();
                    if (trace_expr)
                        printf("[%s:%d] unary '-' unary %p tok %p tnext %p\n", __FUNCTION__, __LINE__, (void *)unary, (void *)tok, (void *)tnext);
                }
                if (!checkOperand(tok->value) && !checkOperator(tok->value)) {
                    printf("[%s:%d] OPERAND CHECKFAILLLLLLLLLLLLLLL %s from %s\n", __FUNCTION__, __LINE__, tree2str(tok).c_str(), lexString.c_str());
                    exit(-1);
                }
                while (tnext && (isParen(tnext->value) || isIdChar(tnext->value[0]))) {
                    assert(isIdChar(tok->value[0]));
                    tok->operands.push_back(tnext);
                    tnext = get1Token();
                }
                repeatGet1Token = tnext;
                if (unary) {
                    unary->operands.push_back(tok);
                    tok = unary;
                }
                currentOperand = tok;
            }
            else {                        /* Operator */
                std::string L = TOP ? TOP->value : "", R = tok->value;
                if (!checkOperator(R)) {
                    printf("[%s:%d] OPERATOR CHECKFAILLLLLLLLLLLLLLL %s from %s\n", __FUNCTION__, __LINE__, R.c_str(), lexString.c_str());
                    exit(-1);
                }
                else if (!((L == R && L != "?") || (L == "?" && R == ":"))) {
                    if (TOP) {
                        int lprec = findPrec(L), rprec = findPrec(R);
                        if (lprec < rprec) {
                            exprStackIndex++;
                            TOP = nullptr;
                        }
                        else {
                            TOP->operands.push_back(currentOperand);
                            currentOperand = TOP;
                            while (exprStackIndex > 0 && lprec >= rprec) {
                                exprStackIndex--;
                                TOP->operands.push_back(currentOperand);
                                currentOperand = TOP;
                                L = TOP->value;
                                lprec = findPrec(L);
                            }
                        }
                    }
                    TOP = tok;
                }
                TOP->operands.push_back(currentOperand);
                currentOperand = nullptr;
            }
        }
        while (exprStackIndex != 0) {
            TOP->operands.push_back(currentOperand);
            currentOperand = TOP;
            exprStackIndex--;
        }
        if (currentOperand) {
            if (TOP)
                TOP->operands.push_back(currentOperand);
            else
                TOP = currentOperand;
        }
        if (TOP) {
            if (terminator != "")
                head->operands.push_back(TOP); // the first item in a recursed list
            else
                head = TOP;
        }
    }
    head = cleanupExpr(head, preserveParen);
    return head;
}
コード例 #11
0
ファイル: expr.cpp プロジェクト: cambridgehackers/atomicc
static DdNode *tree2BDD(DdManager *mgr, ACCExpr *expr, VarMap &varMap)
{
    std::string op = expr->value;
    DdNode *ret = nullptr;
    if (op == "&&")
        op = "&";
    else if (op == "||")
        op = "|";
    if (checkInteger(expr, "1"))
        ret = Cudd_ReadOne(mgr);
    else if (checkInteger(expr, "0"))
        ret = Cudd_ReadLogicZero(mgr);
    else if (op == "!")
        return Cudd_Not(tree2BDD(mgr, expr->operands.front(), varMap)); // Not passes through ref count
    else if (op != "&" && op != "|" && op != "^") {
        if ((op == "!=" || op == "==")) {
            ACCExpr *lhs = getRHS(expr, 0);
            if (boolPossible(lhs) && boolPossible(getRHS(expr,1)))
                goto next; // we can analyze relops on booleans
            if (trace_bool)
                printf("[%s:%d] boolnot %d %d = %s\n", __FUNCTION__, __LINE__, boolPossible(getRHS(expr,0)), boolPossible(getRHS(expr,1)), tree2str(expr).c_str());
            if (isIdChar(lhs->value[0])) {
                if (trace_bool)
                    printf("[%s:%d] name %s type %s\n", __FUNCTION__, __LINE__, lhs->value.c_str(), refList[lhs->value].type.c_str());
            }
        }
        if (op == "!=")    // normalize comparison strings
            expr->value = "==";
        std::string name = "( " + tree2str(expr) + " )";
        if (!varMap[name]) {
            varMap[name] = new MapItem;
            varMap[name]->index = varMap.size();
            varMap[name]->node = Cudd_bddIthVar(mgr, varMap[name]->index);
        }
        ret = varMap[name]->node;
        if (op == "!=") {   // normalize comparison strings
            expr->value = op; // restore
            ret = Cudd_Not(ret);
        }
    }
    if (ret) {
        Cudd_Ref(ret);
        return ret;
    }
next:;
    for (auto item: expr->operands) {
         DdNode *operand = tree2BDD(mgr, item, varMap), *next;
         if (!ret)
             ret = operand;
         else {
             if (op == "&")
                 next = Cudd_bddAnd(mgr, ret, operand);
             else if (op == "|")
                 next = Cudd_bddOr(mgr, ret, operand);
             else if (op == "^" || op == "!=")
                 next = Cudd_bddXor(mgr, ret, operand);
             else if (op == "==")
                 next = Cudd_bddXnor(mgr, ret, operand);
             else {
                 printf("[%s:%d] unknown operator\n", __FUNCTION__, __LINE__);
                 exit(-1);
             }
             Cudd_Ref(next);
             Cudd_RecursiveDeref(mgr, operand);
             Cudd_RecursiveDeref(mgr, ret);
             ret = next;
         }
    }
    return ret;
}
コード例 #12
0
ファイル: expr.cpp プロジェクト: cambridgehackers/atomicc
static ACCExpr *get1Token(void)
{
    std::string lexToken;
    auto getNext = [&] (void) -> void {
        lexToken += lexChar;
        lexChar = lexString[lexIndex++];
    };

    ACCExpr *ret = repeatGet1Token;
    repeatGet1Token = nullptr;
    if (ret)
        return ret;
    while (lexChar == ' ' || lexChar == '\t')
        lexChar = lexString[lexIndex++];
    if(lexIndex > lexString.length() || lexChar == 0)
        return nullptr;
    if (isIdChar(lexChar)) {
        do {
            getNext();
        } while (isIdChar(lexChar) || isdigit(lexChar));
        if (lexAllowRange && lexChar == '[') {
            do {
                getNext();
            } while (lexChar != ']');
            getNext();
        }
        if (lexToken == "__defaultClock")
            lexToken = "CLK";
        else if (lexToken == "__defaultnReset")
            lexToken = "nRST";
    }
    else if (isdigit(lexChar))
        do {
            getNext();
        } while (isdigit(lexChar) || lexChar == '.' || lexChar == '\'' || lexChar == 'b'
            || lexChar == 'h' || lexChar == 'd' || lexChar == 'o');
    else if (lexChar == '+' || lexChar == '-' || lexChar == '*' || lexChar == '&' || lexChar == '|')
        do {
            getNext();
        } while (lexChar == lexToken[0]);
    else if (lexChar == '=' || lexChar == '<' || lexChar == '>' || lexChar == '!')
        do {
            getNext();
        } while (lexChar == '=' || lexChar == '<' || lexChar == '>');
    else if (isParen(lexChar) || lexChar == '/' || lexChar == '%' || lexChar == '.'
        || lexChar == ']' || lexChar == '}' || lexChar == ')' || lexChar == '^'
        || lexChar == ',' || lexChar == '?' || lexChar == ':' || lexChar == ';')
        getNext();
    else if (lexChar == '@') { // special 'escape' character for internal SUBSCRIPT_MARKER/PARAMETER_MARKER sequences
        getNext();
        getNext();
    }
    else if (lexChar == '"') {
        do {
            if (lexChar == '\\')
                getNext();
            getNext();
        } while (lexChar != '"');
        getNext();
    }
    else {
        printf("[%s:%d] lexString '%s' unknown lexChar %c %x\n", __FUNCTION__, __LINE__, lexString.c_str(), lexChar, lexChar);
        exit(-1);
    }
    ret = allocExpr(lexToken);
    if (isParen(ret->value)) {
        std::string val = ret->value;
        if (trace_expr)
            printf("[%s:%d] before subparse of '%s'\n", __FUNCTION__, __LINE__, ret->value.c_str());
        ret = getExprList(ret, treePost(ret).substr(1), false, true);
        if (ret->value != val)
            ret = allocExpr(val, ret); // over optimization of '(<singleItem>)'
        if (trace_expr) {
            printf("[%s:%d] after subparse of '%s'\n", __FUNCTION__, __LINE__, ret->value.c_str());
            dumpExpr("SUBPAREN", ret);
        }
    }
    return ret;
}