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

📄 semantic.c

📁 cg编译器
💻 C
📖 第 1 页 / 共 2 页
字号:
                    if (IsOutVal) {
                        lScope = Cg->theHAL->varyingOut->type->str.members;
                    } else {
                        lScope = Cg->theHAL->varyingIn->type->str.members;
                    }
                } else {
                    SemanticError(&fSymb->loc, ERROR_S_SEMANTIC_NOT_DEFINED_VOUT,
                                  GetAtomString(atable, fSymb->name));
                }
            }
        }
        if (lScope) {
            lBind->none.lname = lname;
            fSymb->details.var.bind = lBind;
            if (!(lBind->none.properties & BIND_HIDDEN)) {
                lSymb = LookUpLocalSymbol(lScope, lname);
                if (lSymb) {
                    // Already defined - second use of this name.
                } else {
                    lSymb = AddSymbol(&fSymb->loc, lScope, lname, fSymb->type, VARIABLE_S);
                    lSymb->details.var.bind = lBind;
                    if (lScope->symbols != lSymb) {
                        mSymb = lScope->symbols;
                        while (mSymb->next)
                            mSymb = mSymb->next;
                        mSymb->next = lSymb;
                    }
                }
            }
        }
        break;
    case TYPE_CATEGORY_STRUCT:
        SemanticError(&fSymb->loc, ERROR_S_NESTED_SEMANTIC_STRUCT,
                      GetAtomString(atable, fSymb->name));
        break;
    default:
        SemanticError(&fSymb->loc, ERROR_S_ILLEGAL_PARAM_TO_MAIN,
                      GetAtomString(atable, fSymb->name));
        break;
    }
    return lSymb;
} // lBindVaryingVariable

/*
 * lVerifyConnectorDirection() - Verify that this connector name is valid for the current
 *         profile and is of the appropriate direction.
 */

static void lVerifyConnectorDirection(SourceLoc *loc, int semantics, int IsOutParam)
{
    int cid, uses;

    // If connector semantics present make sure that connector direction matches parameter's:

    if (semantics) {
        cid = Cg->theHAL->GetConnectorID(semantics);
        if (cid) {
            uses = Cg->theHAL->GetConnectorUses(cid, Cg->theHAL->pid);
            if (IsOutParam) {
                if (!(uses & CONNECTOR_IS_OUTPUT))
                    SemanticError(loc, ERROR_S_CONNECT_FOR_INPUT,
                                  GetAtomString(atable, semantics));
            } else {
                if (!(uses & CONNECTOR_IS_INPUT))
                    SemanticError(loc, ERROR_S_CONNECT_FOR_OUTPUT,
                                  GetAtomString(atable, semantics));
            }
        } else {
            SemanticError(loc, ERROR_S_CONNECTOR_TYPE_INVALID,
                          GetAtomString(atable, semantics));
        }
    }
} // lVerifyConnectorDirection

/*
 * BuildSemanticStructs() - Build the three global semantic type structure,  Check main for
 *         type errors in its arguments.
 */

void BuildSemanticStructs(SourceLoc *loc, Scope *fScope, Symbol *program)
{
    int category, domain, qualifiers, len, rlen;
    Scope *vinScope, *voutScope, *lScope;
    Type *vinType, *voutType;
    Symbol *vinVar, *voutVar;
    int vinTag, voutTag;
    Symbol *formal, *member, *lSymb;
    expr *lExpr, *rExpr, *vExpr;
    Type *lType, *rettype;
    StmtList instmts, outstmts;
    Binding *lBind;
    int IsOutParam;
    float lVal[4];
    stmt *lStmt;

    // Define pseudo type structs for semantics:

    vinScope = NewScope();
    vinScope->HasSemantics = 1;
    vinScope->level = 1;
    vinScope->IsStructScope = 1;
    voutScope = NewScope();
    voutScope->HasSemantics = 1;
    voutScope->level = 1;
    voutScope->IsStructScope = 1;

    vinTag = AddAtom(atable, "$vin");
    vinType = StructHeader(loc, fScope, 0, vinTag);
    vinType->str.members = vinScope;
    Cg->theHAL->varyingIn = vinVar = DefineVar(loc, fScope, vinTag, vinType);
    //vinTypedef = DefineTypedef(loc, fScope, vinTag, vinType); // Not sure this is neessary
    voutTag = AddAtom(atable, "$vout");
    voutType = StructHeader(loc, fScope, 0, voutTag);
    voutType->str.members = voutScope;
    Cg->theHAL->varyingOut = voutVar = DefineVar(loc, fScope, voutTag, voutType);
    //voutTypedef = DefineTypedef(loc, fScope, voutTag, voutType); // Not sure this is neessary

    instmts.first = instmts.last = NULL;
    outstmts.first = outstmts.last = NULL;

    // Walk list of formals creating semantic struct members for all parameters:

    formal = program->details.fun.params;
    while (formal) {
        category = GetCategory(formal->type);
        domain = GetDomain(formal->type);
        qualifiers = GetQualifiers(formal->type);
        if ((qualifiers & TYPE_QUALIFIER_INOUT) == TYPE_QUALIFIER_INOUT)
            SemanticError(&formal->loc, ERROR_S_MAIN_PARAMS_CANT_BE_INOUT,
                          GetAtomString(atable, formal->name));
        if (domain == TYPE_DOMAIN_UNIFORM) {
            if (qualifiers & TYPE_QUALIFIER_OUT) {
                SemanticError(&formal->loc, ERROR_S_UNIFORM_ARG_CANT_BE_OUT,
                              GetAtomString(atable, formal->name));
            }
            switch (category) {
            case TYPE_CATEGORY_SCALAR:
            case TYPE_CATEGORY_ARRAY:
            case TYPE_CATEGORY_STRUCT:
                if (lBindUniformVariable(formal, program->name, 1) && formal->details.var.init) {
                    formal->details.var.init = FoldConstants(formal->details.var.init);
                    GetVectorConst(lVal, formal->details.var.init);
                    lBind = NewConstDefaultBinding(0, formal->name, 4, 0, 0, lVal);
                    lBind->constdef.kind = BK_DEFAULT;
                    AddDefaultBinding(lBind);
                }
                break;
            default:
                SemanticError(&formal->loc, ERROR_S_ILLEGAL_PARAM_TO_MAIN,
                              GetAtomString(atable, formal->name));
                break;
            }
        } else {
            IsOutParam = (qualifiers & TYPE_QUALIFIER_OUT) != 0;
            switch (category) {
            case TYPE_CATEGORY_SCALAR:
            case TYPE_CATEGORY_ARRAY:
                lSymb = lBindVaryingVariable(formal, program->name, IsOutParam, 0, 0);
                if (lSymb) {
                    lBind = lSymb->details.var.bind;
                    if (lBind && !(lBind->none.properties & BIND_HIDDEN)) {
                        lExpr = GenSymb(formal);
                        if (IsScalar(formal->type) || IsVector(formal->type, &len)) {
                            if (lBind->none.properties & BIND_INPUT) {
                                // Assign $vin member to bound variable:
                                vExpr = (expr *) NewSymbNode(VARIABLE_OP, vinVar);
                                rExpr = GenMemberReference(vExpr, lSymb);
                                if (IsVector(lSymb->type, &rlen))
                                    rExpr = GenConvertVectorLength(rExpr, GetBase(lSymb->type), rlen, len);
                                lStmt = NewSimpleAssignmentStmt(&program->loc, lExpr, rExpr, 0);
                                AppendStatements(&instmts, lStmt);
                            } else {
                                // Assign bound variable to $vout member:
                                vExpr = (expr *) NewSymbNode(VARIABLE_OP, voutVar);
                                rExpr = GenMemberReference(vExpr, lSymb);
                                if (IsVector(lSymb->type, &rlen))
                                    lExpr = GenConvertVectorLength(lExpr, GetBase(formal->type), len, rlen);
                                lStmt = NewSimpleAssignmentStmt(&program->loc, rExpr, lExpr, 0);
                                AppendStatements(&outstmts, lStmt);
                            }
                        } else {
                            FatalError("Parameter of unsupported type");
                            // xxx
                        }
                    }
                }
                break;
            case TYPE_CATEGORY_STRUCT:
                lType = formal->type;
                lVerifyConnectorDirection(&formal->loc, lType->str.semantics, IsOutParam);
                lScope = lType->str.members;
                member = lScope->symbols;
                while (member) {
                    lSymb = lBindVaryingVariable(member, lType->str.tag, IsOutParam, 1,
                                                 lType->str.semantics);
                    if (lSymb) {
                        lBind = lSymb->details.var.bind;
                        if (lBind && !(lBind->none.properties & BIND_HIDDEN)) {
                            lExpr = GenMemberReference((expr *) NewSymbNode(VARIABLE_OP, formal), member);
                            if (IsScalar(member->type) || IsVector(member->type, &len)) {
                                if (lBind->none.properties & BIND_INPUT) {
                                    // Assign $vin member to bound variable:
                                    vExpr = (expr *) NewSymbNode(VARIABLE_OP, vinVar);
                                    rExpr = GenMemberReference(vExpr, lSymb);
                                    if (IsVector(lSymb->type, &rlen))
                                        rExpr = GenConvertVectorLength(rExpr, GetBase(lSymb->type), rlen, len);
                                    lStmt = NewSimpleAssignmentStmt(&program->loc, lExpr, rExpr, 0);
                                    AppendStatements(&instmts, lStmt);
                                } else {
                                    // Assign bound variable to $vout member:
                                    vExpr = (expr *) NewSymbNode(VARIABLE_OP, voutVar);
                                    rExpr = GenMemberReference(vExpr, lSymb);
                                    if (IsVector(lSymb->type, &rlen))
                                        lExpr = GenConvertVectorLength(lExpr, GetBase(member->type), len, rlen);
                                    lStmt = NewSimpleAssignmentStmt(&program->loc, rExpr, lExpr, 0);
                                    AppendStatements(&outstmts, lStmt);
                                }
                            } else {
                                FatalError("Parameter of unsupported type");
                                // xxx
                            }
                        }
                    }
                    member = member->next;
                }
                break;
            default:
                SemanticError(&formal->loc, ERROR_S_ILLEGAL_PARAM_TO_MAIN,
                              GetAtomString(atable, formal->name));
                break;
            }
        }
        formal = formal->next;
    }

    // Add return value's semantics to the $vout connector:

    lType = program->type;
    rettype = lType->fun.rettype;
    category = GetCategory(rettype);
    if (!IsVoid(rettype)) {
        if (category == TYPE_CATEGORY_STRUCT) {
            lVerifyConnectorDirection(&program->loc, rettype->str.semantics, 1);
            lScope = rettype->str.members;
            member = lScope->symbols;
            while (member) {
                lSymb = lBindVaryingVariable(member, rettype->str.tag, 1, 1,
                                             rettype->str.semantics);
                member = member->next;
            }
        } else {
            SemanticError(&program->loc, ERROR_S_PROGRAM_MUST_RETURN_STRUCT,
                          GetAtomString(atable, program->name));
        }
    }

    // Set the output connector variety:

    voutType->str.variety = Cg->theHAL->outcid;

    // Append initial and final assignment statements to beginning and end of main:

    program->details.fun.statements = ConcatStmts(instmts.first, program->details.fun.statements);
    program->details.fun.statements = ConcatStmts(program->details.fun.statements, outstmts.first);

} // BuildSemanticStructs


void BindDefaultSemantic(Symbol *lSymb, int category, int gname)
{
    Binding *lBind;
    float lVal[4];

    switch (category) {
    case TYPE_CATEGORY_SCALAR:
    case TYPE_CATEGORY_ARRAY:
    case TYPE_CATEGORY_STRUCT:
        gname = 0;
        if (lBindUniformVariable(lSymb, gname, 0) && lSymb->details.var.init) {
            lSymb->details.var.init = FoldConstants(lSymb->details.var.init);
            GetVectorConst(lVal, lSymb->details.var.init);
            lBind = NewConstDefaultBinding(0, lSymb->name, 4, 0, 0, lVal);
            lBind->constdef.kind = BK_DEFAULT;
            AddDefaultBinding(lBind);
        }
        break;
    default:
        SemanticError(&lSymb->loc, ERROR_S_NON_STATIC_GLOBAL_TYPE_ERR,
                      GetAtomString(atable, lSymb->name));
    }
    lSymb->properties &= ~SYMB_NEEDS_BINDING;
} // BindDefaultSemantic

⌨️ 快捷键说明

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