⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 support.c

📁 cg编译器
💻 C
📖 第 1 页 / 共 5 页
字号:
    int DiffParamTypes, DiffParamQualifiers, DiffParamCount, DiffReturnType;
    TypeList *oldArgType, *newArgType;
    Symbol *lSymb;
    int index, group, OK;

    if (fSymb) {
        if (GetCategory(fSymb->type) != TYPE_CATEGORY_FUNCTION) {
            SemanticError(loc, ERROR_S_NAME_ALREADY_DEFINED, GetAtomString(atable, atom));
            lSymb = fSymb;
        } else {
            OK = 1;
            lSymb = fSymb;
            while (lSymb) {
                if (GetCategory(fSymb->type) != TYPE_CATEGORY_FUNCTION) {
                    InternalError(loc, ERROR_S_SYMBOL_TYPE_NOT_FUNCTION,
                                  GetAtomString(atable, lSymb->name));
                    return fSymb;
                }
                DiffParamTypes = DiffParamQualifiers = DiffParamCount = DiffReturnType = 0;
                if (!IsSameUnqualifiedType(lSymb->type->fun.rettype, fType->fun.rettype))
                    DiffReturnType = 1;
                oldArgType = lSymb->type->fun.paramtypes;
                newArgType = fType->fun.paramtypes;
                while (newArgType && oldArgType) {
                    if (!IsSameUnqualifiedType(oldArgType->type, newArgType->type)) {
                        DiffParamTypes = 1;
                    } else if (GetQualifiers(oldArgType->type) != GetQualifiers(newArgType->type)) {
                        DiffParamQualifiers = 1;
                    }
                    oldArgType = oldArgType->next;
                    newArgType = newArgType->next;
                }
                if (newArgType || oldArgType)
                    DiffParamCount = 1;
                if (!DiffParamCount && !DiffParamTypes) {
                    if (DiffParamQualifiers) {
                        SemanticError(loc, ERROR_S_OVERLOAD_DIFF_ONLY_QUALS,
                                      GetAtomString(atable, atom));
                        OK = 0;
                        break;
                    }
                    if (DiffReturnType) {
                        SemanticError(loc, ERROR_S_OVERLOAD_DIFF_ONLY_RETURN,
                                      GetAtomString(atable, atom));
                        OK = 0;
                        break;
                    }
                    break; // Found the matching function
                }
                lSymb = lSymb->details.fun.overload;
            }
            if (OK) {
                if (DiffParamCount || DiffParamTypes) {
                    lSymb = NewSymbol(loc, fScope, atom, fType, FUNCTION_S);
                    lSymb->details.fun.params = params;
                    lSymb->details.fun.locals = locals;
                    lSymb->details.fun.overload = fSymb->details.fun.overload;
                    fSymb->details.fun.overload = lSymb;
                    if (GetCategory(fType) == TYPE_CATEGORY_FUNCTION) {
                        locals->returnType = fType->fun.rettype;
                    } else {
                        locals->returnType = UndefinedType;
                    }
                } else {
                    if (!(lSymb->properties & SYMB_IS_DEFINED)) {
                        // Overwrite previous definitions if this function is not yet defined.
                        // Prototype parameter names are ignored.
                        lSymb->details.fun.params = params;
                        lSymb->details.fun.locals = locals;
                    } else {
                        // Declarator for a function that's already been defined.  Not an error.
                    }
                }
            } else {
                // Found a function that differs only by qualifiers or return type.  Error arleady issued.
                // lSymb = fSymb;
            }
        }
    } else {
        lSymb = AddSymbol(loc, fScope, atom, fType, FUNCTION_S);
        lSymb->details.fun.params = params;
        lSymb->details.fun.locals = locals;
        if (GetCategory(fType) == TYPE_CATEGORY_FUNCTION) {
            locals->returnType = fType->fun.rettype;
        } else {
            locals->returnType = UndefinedType;
        }
    }
    if (lSymb->type->properties & TYPE_MISC_INTERNAL) {
        index = Cg->theHAL->CheckInternalFunction(lSymb, &group);
        if (index) {
            //
            // lSymb->InternalIndex = index; etc.
            //
            lSymb->properties |= SYMB_IS_DEFINED | SYMB_IS_BUILTIN;
            lSymb->details.fun.group = group;
            lSymb->details.fun.index = index;
        } else {
            SemanticError(loc, ERROR_S_INVALID_INTERNAL_FUNCTION, GetAtomString(atable, atom));
        }
    }

    return lSymb;
} // DeclareFunc

/*
 * DefineFunction() - Set the body of the function "func" to the statements in "body".
 *
 */

void DefineFunction(SourceLoc *loc, Scope *fScope, decl *func, stmt *body)
{
    Symbol *lSymb = func->symb;
    SymbolList *lSymbList;
    Scope *globals;
    Type *lType;

    if (IsFunction(lSymb)) {
        if (body) {
            if (lSymb->properties & SYMB_IS_DEFINED) {
                SemanticError(loc, ERROR_S_FUN_ALREADY_DEFINED,
                              GetAtomString(atable, lSymb->name));
            } else {
                lSymb->properties |= SYMB_IS_DEFINED;
                lSymb->details.fun.statements = body;
                lType = lSymb->type;
                if ((lType->properties & TYPE_MISC_INLINE) ||
                    Cg->theHAL->GetCapsBit(CAPS_INLINE_ALL_FUNCTIONS))
                {
                    lSymb->properties |= SYMB_IS_INLINE_FUNCTION;
                }
            }
            if (!fScope->HasReturnStmt && !IsVoid(fScope->returnType)) {
                SemanticError(loc, ERROR_S_FUNCTION_HAS_NO_RETURN,
                              GetAtomString(atable, lSymb->name));
            }
            if (func->type.type.properties & TYPE_MISC_PROGRAM) {
                globals = fScope->parent;
                if (!globals->programs) {
                    lSymbList = (SymbolList *) malloc(sizeof(SymbolList));
                    lSymbList->next = globals->programs;
                    lSymbList->symb = lSymb;
                    globals->programs = lSymbList;
                } else {
                    SemanticError(loc, ERROR_S_ONE_PROGRAM,
                                  GetAtomString(atable, globals->programs->symb->name));
                }
            }
        } else {
            SemanticError(loc, ERROR_S_NO_STATEMENTS, GetAtomString(atable, func->name));
        }
        if (Cg->options.DumpParseTree) {
            PrintScopeDeclarations();
            PrintFunction(lSymb);
        }
    }
} // DefineFunction

/*
 * GlobalInitStatements()
 *
 */

int GlobalInitStatements(Scope *fScope, stmt *fStmt)
{
    stmt *lStmt;

    if (fStmt) {
        if (fScope->initStmts) {
            lStmt = fScope->initStmts;
            while (lStmt->commonst.next)
                lStmt = lStmt->commonst.next;
            lStmt->commonst.next = fStmt;
        } else {
            fScope->initStmts = fStmt;
        }
    }
    return 1;
} // GlobalInitStatements

/*
 * BasicVariable() - A variable identifier has been encountered.
 *
 */

expr *BasicVariable(SourceLoc *loc, int name)
{
    Symbol *lSymb;
    
    lSymb = LookUpSymbol(CurrentScope, name);
    if (!lSymb) {
        SemanticError(loc, ERROR_S_UNDEFINED_VAR, GetAtomString(atable, name));
        lSymb = DefineVar(loc, CurrentScope, name, UndefinedType);
    }
    return (expr *) NewSymbNode(VARIABLE_OP, lSymb);
} // BasicVariable

/*
 * IsLValue() - Is this expression an l-value?
 *
 */

int IsLValue(const expr *fExpr)
{
    if (fExpr) {
        return fExpr->common.IsLValue;
    } else {
        return 0;
    }
} // IsLValue

/*
 * IsConst() - Is this expression an l-value?
 *
 */

int IsConst(const expr *fExpr)
{
    if (fExpr) {
        return fExpr->common.IsConst;
    } else {
        return 0;
    }
} // IsConst

/*
 * IsArrayIndex() - Is this expression an array index expression?
 *
 */

int IsArrayIndex(const expr *fExpr)
{
    if (fExpr) {
        return fExpr->common.kind == BINARY_N && fExpr->bin.op == ARRAY_INDEX_OP;
    } else {
        return 0;
    }
} // IsArrayIndex

/*
 * lIsBaseCastValid() - Is it O.K. to cast the base type fromBase to toBase?
 *
 */

static int lIsBaseCastValid(int toBase, int fromBase, int Explicit)
{
    if (toBase == TYPE_BASE_NO_TYPE || fromBase == TYPE_BASE_NO_TYPE)
        return 0;
    if (toBase == TYPE_BASE_VOID || fromBase == TYPE_BASE_VOID)
        return 0;
    if (toBase == fromBase)
        return 1;
    if (Cg->theHAL->IsValidScalarCast(toBase, fromBase, Explicit)) {
        return 1;
    } else {
        return 0;
    }
} // lIsBaseCastValid

/*
 * ConvertType() - Type cast fExpr from fromType to toType if needed.  Ignore qualifiers.
 *
 * If "result" is NULL just check validity of cast; don't allocate cast operator node.
 *
 */

int ConvertType(expr *fExpr, Type *toType, Type *fromType, expr **result, int IgnorePacked, int Explicit)
{
    int fcategory, tcategory;
    int fbase, tbase;
    Type *feltype, *teltype;
    unary *unnode;
    int ToPacked, FromPacked;

    ToPacked = (toType->properties & TYPE_MISC_PACKED) != 0;
    FromPacked = (fromType->properties & TYPE_MISC_PACKED) != 0;
    if (IsSameUnqualifiedType(toType, fromType) &&
        ((ToPacked == FromPacked) || IgnorePacked))
    {
        if (result)
            *result = fExpr;
        return 1;
    } else {
        fcategory = GetCategory(fromType);
        tcategory = GetCategory(toType);
        if (fcategory == tcategory) {
            switch (fcategory) {
            case TYPE_CATEGORY_SCALAR:
                fbase = GetBase(fromType);
                tbase = GetBase(toType);
                if (lIsBaseCastValid(tbase, fbase, Explicit)) {
                    if (result) {
                        unnode = NewUnopSubNode(CAST_CS_OP, SUBOP_CS(tbase, fbase), fExpr);
                        unnode->type = GetStandardType(tbase, 0, 0);
                        unnode->HasSideEffects = fExpr->common.HasSideEffects;
                        *result = (expr *) unnode;
                    }
                    return 1;
                } else {
                    return 0;
                }
                break;
            case TYPE_CATEGORY_ARRAY:
                if (toType->arr.numels != fromType->arr.numels)
                    return 0;
                if (toType->arr.numels > 4)
                    return 0;
                if (!IgnorePacked && (ToPacked != FromPacked))
                    return 0;
                feltype = fromType->arr.eltype;
                teltype = toType->arr.eltype;
                fcategory = GetCategory(feltype);
                tcategory = GetCategory(teltype);
                if (tcategory != TYPE_CATEGORY_SCALAR || fcategory != TYPE_CATEGORY_SCALAR)
                    return 0;
                fbase = GetBase(feltype);
                tbase = GetBase(teltype);
                if (lIsBaseCastValid(tbase, fbase, Explicit)) {
                    if (result) {
                        unnode = NewUnopSubNode(CAST_CV_OP, SUBOP_CV(tbase, toType->arr.numels, fbase), fExpr);
                        unnode->type = GetStandardType(tbase, toType->arr.numels, 0);
                        unnode->HasSideEffects = fExpr->common.HasSideEffects;
                        *result = (expr *) unnode;
                    }
                    return 1;
                } else {
                    return 0;
                }
                break;
            default:
                return 0;
            }
        } else {
            return 0;
        }
    }
} // ConvertType

/*
 * CastScalarVectorMatrix() - Cast a scalar, vector, or matrix expression.
 *
 * Scalar: len = 0.
 * Vector: len >= 1 and len2 = 0
 * Matrix: len >= 1 and len2 >= 1
 *
 * len = 1 means "float f[1]" not "float f"
 *
 */

expr *CastScalarVectorMatrix(expr *fExpr, int fbase, int tbase, int len, int len2)
{
    int op, subop;
    expr *lExpr;

    if (len == 0) {
        op = CAST_CS_OP;
        subop = SUBOP_CS(tbase, fbase);
    } else if (len2 == 0) {
        op = CAST_CV_OP;
        subop = SUBOP_CV(tbase, len, fbase);
    } else {
        op = CAST_CM_OP;
        subop = SUBOP_CM(len2, tbase, len, fbase);
    }
    lExpr = (expr *) NewUnopSubNode(op, subop, fExpr);
    lExpr->common.type = GetStandardType(tbase, len, len2);
    return lExpr;
} // CastScalarVectorMatrix

/*
 * ConvertNumericOperands() - Convert two scalar, vector, or matrix expressions to the same type
 *         for use in an expression.  Number of dimensions and lengths may differ.
 *
 * Returns: base type of resulting values.
 *
 */

int ConvertNumericOperands(int baseop, expr **lExpr, expr **rexpr, int lbase, int rbase,
                           int llen, int rlen, int llen2, int rlen2)
{
    int nbase;

    nbase = Cg->theHAL->GetBinOpBase(baseop, lbase, rbase, llen, rlen);
    if (nbase != lbase)
        *lExpr = CastScalarVectorMatrix(*lExpr, lbase, nbase, llen, llen2);
    if (nbase != rbase)
        *rexpr = CastScalarVectorMatrix(*rexpr, rbase, nbase, rlen, rlen2);
    return nbase;
} // ConvertNumericOperands

/*
 * CheckBooleanExpr()
 *
 */

expr *CheckBooleanExpr(SourceLoc *loc, expr *fExpr, int AllowVector)
{
    int len = 0, HasError = 0;
    Type *lType, *leltype;

    lType = leltype = fExpr->common.type;
    if (IsScalar(lType)) {
        if (!IsBoolean(lType)) {
            SemanticError(loc, ERROR___BOOL_EXPR_EXPECTED);
            HasError = 1;
        }
    } else if (IsVector(lType, &len)) {
        leltype = lType->arr.eltype;
        if (AllowVector) {
            if (len > 4) {
                SemanticError(loc, ERROR___VECTOR_EXPR_LEN_GR_4);
                HasError = 1;
                len = 4;
            }
            if (!IsBoolean(lType)) {
                Semant

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -