Esempio n. 1
0
static void initVariantInstance(InstancePtr x) {
    EnvPtr env = new Env(x->env);
    const vector<PatternVar> &pvars = x->patternVars;
    for (unsigned i = 0; i < pvars.size(); ++i) {
        if (pvars[i].isMulti) {
            MultiPatternCellPtr cell = new MultiPatternCell(NULL);
            addLocal(env, pvars[i].name, cell.ptr());
        }
        else {
            PatternCellPtr cell = new PatternCell(NULL);
            addLocal(env, pvars[i].name, cell.ptr());
        }
    }
    PatternPtr pattern = evaluateOnePattern(x->target, env);
    ObjectPtr y = derefDeep(pattern);
    if (y.ptr()) {
        if (y->objKind != TYPE)
            error(x->target, "not a variant type");
        Type *z = (Type *)y.ptr();
        if (z->typeKind != VARIANT_TYPE)
            error(x->target, "not a variant type");
        VariantType *vt = (VariantType *)z;
        vt->variant->instances.push_back(x);
    }
    else {
        if (pattern->kind != PATTERN_STRUCT)
            error(x->target, "not a variant type");
        PatternStruct *ps = (PatternStruct *)pattern.ptr();
        if ((!ps->head) || (ps->head->objKind != VARIANT))
            error(x->target, "not a variant type");
        Variant *v = (Variant *)ps->head.ptr();
        v->instances.push_back(x);
    }
}
Esempio n. 2
0
void convertFreeVars(LambdaPtr x, EnvPtr env,
                     const string &closureDataName,
                     vector<string> &freeVars)
{
    EnvPtr env2 = new Env(env);
    for (unsigned i = 0; i < x->formalArgs.size(); ++i) {
        FormalArgPtr arg = x->formalArgs[i];
        addLocal(env2, arg->name, arg->name.ptr());
    }
    if (x->formalVarArg.ptr()) {
        addLocal(env2, x->formalVarArg->name, x->formalVarArg->name.ptr());
    }
    LambdaContext ctx(x->captureByRef, env, closureDataName, freeVars);
    convertFreeVars(x->body, env2, ctx);
}
Esempio n. 3
0
File: loader.cpp Progetto: Blei/clay
static EnvPtr overloadPatternEnv(OverloadPtr x) {
    EnvPtr env = new Env(x->env);
    llvm::ArrayRef<PatternVar> pvars = x->code->patternVars;
    for (unsigned i = 0; i < pvars.size(); ++i) {
        if (pvars[i].isMulti) {
            MultiPatternCellPtr cell = new MultiPatternCell(NULL);
            addLocal(env, pvars[i].name, cell.ptr());
        }
        else {
            PatternCellPtr cell = new PatternCell(NULL);
            addLocal(env, pvars[i].name, cell.ptr());
        }
    }
    return env;
}
Esempio n. 4
0
static void initializePatterns(OverloadPtr x)
{
    if (x->patternsInitializedState == 1)
        return;
    if (x->patternsInitializedState == -1)
        error("unholy recursion detected");
    assert(x->patternsInitializedState == 0);
    x->patternsInitializedState = -1;

    CodePtr code = x->code;
    const vector<PatternVar> &pvars = code->patternVars;
    x->patternEnv = new Env(x->env);
    for (unsigned i = 0; i < pvars.size(); ++i) {
        if (pvars[i].isMulti) {
            MultiPatternCellPtr multiCell = new MultiPatternCell(NULL);
            x->multiCells.push_back(multiCell);
            x->cells.push_back(NULL);
            addLocal(x->patternEnv, pvars[i].name, multiCell.ptr());
        }
        else {
            PatternCellPtr cell = new PatternCell(NULL);
            x->cells.push_back(cell);
            x->multiCells.push_back(NULL);
            addLocal(x->patternEnv, pvars[i].name, cell.ptr());
        }
    }

    assert(x->target.ptr());
    x->callablePattern = evaluateOnePattern(x->target, x->patternEnv);

    const vector<FormalArgPtr> &formalArgs = code->formalArgs;
    for (unsigned i = 0; i < formalArgs.size(); ++i) {
        FormalArgPtr y = formalArgs[i];
        PatternPtr pattern;
        if (y->type.ptr())
            pattern = evaluateOnePattern(y->type, x->patternEnv);
        x->argPatterns.push_back(pattern);
    }

    if (code->formalVarArg.ptr() && code->formalVarArg->type.ptr()) {
        ExprPtr unpack = new Unpack(code->formalVarArg->type.ptr());
        unpack->location = code->formalVarArg->type->location;
        x->varArgPattern = evaluateMultiPattern(new ExprList(unpack),
                                                x->patternEnv);
    }

    x->patternsInitializedState = 1;
}
Esempio n. 5
0
void ClosureExpression::analyzeVarsForClosureExpression(
  AnalysisResultConstRawPtr /*ar*/) {
  auto const containing = getFunctionScope();
  for (auto const& var : *m_vars) {
    auto const param = dynamic_pointer_cast<ParameterExpression>(var);
    containing->addLocal(param->getName());
  }
}
Esempio n. 6
0
void initializePatternEnv(EnvPtr patternEnv, llvm::ArrayRef<PatternVar> pvars, 
    vector<PatternCellPtr> &cells, vector<MultiPatternCellPtr> &multiCells)
{
    
    for (size_t i = 0; i < pvars.size(); ++i) {
        if (pvars[i].isMulti) {
            MultiPatternCellPtr multiCell = new MultiPatternCell(NULL);
            multiCells.push_back(multiCell);
            cells.push_back(NULL);
            addLocal(patternEnv, pvars[i].name, multiCell.ptr());
        }
        else {
            PatternCellPtr cell = new PatternCell(NULL);
            cells.push_back(cell);
            multiCells.push_back(NULL);
            addLocal(patternEnv, pvars[i].name, cell.ptr());
        }
    }
}
Esempio n. 7
0
Info & Block::addShare(const symbol::Symbol & Lsym, const symbol::Symbol & Rsym, const TIType & Rtype, ast::Exp * exp)
{
    addLocal(Lsym, Rtype, /* isIntIterator */ false);
    Info & Linfo = putAndClear(Lsym, exp);
    Info & Rinfo = putSymsInScope(Rsym);
    Linfo.cleared = false;
    Linfo.type = Rtype;
    Linfo.data = Rinfo.data;
    Linfo.isint = Rinfo.isint;
    Linfo.data->add(Lsym);
    Linfo.exists = true;

    return Linfo;
}
Esempio n. 8
0
Info & Block::addDefine(const symbol::Symbol & sym, const TIType & Rtype, const bool isIntIterator, ast::Exp * exp)
{
    /* DEFINE:
       - if associated data is shared then we need to clone it
    */
    addLocal(sym, Rtype, isIntIterator);
    Info & info = putAndClear(sym, exp);
    info.cleared = false;
    info.data = new Data(true, sym);
    info.type = Rtype;
    info.exists = true;
    dm->registerData(info.data);//, __LINE__, __FILE__);

    return info;
}
Esempio n. 9
0
static void initializeVariantType(VariantTypePtr t) {
    assert(!t->initialized);

    EnvPtr variantEnv = new Env(t->variant->env);
    {
        const vector<IdentifierPtr> &params = t->variant->params;
        IdentifierPtr varParam = t->variant->varParam;
        assert(params.size() <= t->params.size());
        for (unsigned j = 0; j < params.size(); ++j)
            addLocal(variantEnv, params[j], t->params[j]);
        if (varParam.ptr()) {
            MultiStaticPtr ms = new MultiStatic();
            for (unsigned j = params.size(); j < t->params.size(); ++j)
                ms->add(t->params[j]);
            addLocal(variantEnv, varParam, ms.ptr());
        }
        else {
            assert(params.size() == t->params.size());
        }
    }
    ExprListPtr defaultInstances = t->variant->defaultInstances;
    for (unsigned i = 0; i < defaultInstances->size(); ++i) {
        ExprPtr x = defaultInstances->exprs[i];
        TypePtr memberType = evaluateType(x, variantEnv);
        t->memberTypes.push_back(memberType);
    }

    const vector<InstancePtr> &instances = t->variant->instances;
    for (unsigned i = 0; i < instances.size(); ++i) {
        InstancePtr x = instances[i];
        vector<PatternCellPtr> cells;
        vector<MultiPatternCellPtr> multiCells;
        const vector<PatternVar> &pvars = x->patternVars;
        EnvPtr patternEnv = new Env(x->env);
        for (unsigned j = 0; j < pvars.size(); ++j) {
            if (pvars[j].isMulti) {
                MultiPatternCellPtr multiCell = new MultiPatternCell(NULL);
                multiCells.push_back(multiCell);
                cells.push_back(NULL);
                addLocal(patternEnv, pvars[j].name, multiCell.ptr());
            }
            else {
                PatternCellPtr cell = new PatternCell(NULL);
                cells.push_back(cell);
                multiCells.push_back(NULL);
                addLocal(patternEnv, pvars[j].name, cell.ptr());
            }
        }
        PatternPtr pattern = evaluateOnePattern(x->target, patternEnv);
        if (!unifyPatternObj(pattern, t.ptr()))
            continue;
        EnvPtr staticEnv = new Env(x->env);
        for (unsigned j = 0; j < pvars.size(); ++j) {
            if (pvars[j].isMulti) {
                MultiStaticPtr ms = derefDeep(multiCells[j].ptr());
                if (!ms)
                    error(pvars[j].name, "unbound pattern variable");
                addLocal(staticEnv, pvars[j].name, ms.ptr());
            }
            else {
                ObjectPtr v = derefDeep(cells[j].ptr());
                if (!v)
                    error(pvars[j].name, "unbound pattern variable");
                addLocal(staticEnv, pvars[j].name, v.ptr());
            }
        }
        if (x->predicate.ptr())
            if (!evaluateBool(x->predicate, staticEnv))
                continue;
        TypePtr memberType = evaluateType(x->member, staticEnv);
        t->memberTypes.push_back(memberType);
    }

    RecordPtr reprRecord = getVariantReprRecord();
    vector<ObjectPtr> params;
    for (unsigned i = 0; i < t->memberTypes.size(); ++i)
        params.push_back(t->memberTypes[i].ptr());
    t->reprType = recordType(reprRecord, params);

    t->initialized = true;
}
Esempio n. 10
0
void initializeRecordFields(RecordTypePtr t) {
    assert(!t->fieldsInitialized);
    t->fieldsInitialized = true;
    RecordPtr r = t->record;
    if (r->varParam.ptr())
        assert(t->params.size() >= r->params.size());
    else
        assert(t->params.size() == r->params.size());
    EnvPtr env = new Env(r->env);
    for (unsigned i = 0; i < r->params.size(); ++i)
        addLocal(env, r->params[i], t->params[i].ptr());
    if (r->varParam.ptr()) {
        MultiStaticPtr rest = new MultiStatic();
        for (unsigned i = r->params.size(); i < t->params.size(); ++i)
            rest->add(t->params[i]);
        addLocal(env, r->varParam, rest.ptr());
    }
    RecordBodyPtr body = r->body;
    if (body->isComputed) {
        LocationContext loc(body->location);
        AnalysisCachingDisabler disabler;
        MultiPValuePtr mpv = analyzeMulti(body->computed, env);
        vector<TypePtr> fieldInfoTypes;
        if ((mpv->size() == 1) &&
            (mpv->values[0]->type->typeKind == RECORD_TYPE) &&
            (((RecordType *)mpv->values[0]->type.ptr())->record.ptr() ==
             prelude_RecordWithProperties().ptr()))
        {
            const vector<ObjectPtr> &params =
                ((RecordType *)mpv->values[0]->type.ptr())->params;
            assert(params.size() == 2);
            if (params[0]->objKind != TYPE)
                argumentError(0, "expecting a tuple of properties");
            TypePtr param0 = (Type *)params[0].ptr();
            if (param0->typeKind != TUPLE_TYPE)
                argumentError(0, "expecting a tuple of properties");
            TupleTypePtr props = (TupleType *)param0.ptr();
            if (params[1]->objKind != TYPE)
                argumentError(1, "expecting a tuple of fields");
            TypePtr param1 = (Type *)params[1].ptr();
            if (param1->typeKind != TUPLE_TYPE)
                argumentError(1, "expecting a tuple of fields");
            TupleTypePtr fields = (TupleType *)param1.ptr();
            fieldInfoTypes = fields->elementTypes;
            setProperties(t.ptr(), props->elementTypes);
        }
        else {
            for (unsigned i = 0; i < mpv->size(); ++i)
                fieldInfoTypes.push_back(mpv->values[i]->type);
        }
        for (unsigned i = 0; i < fieldInfoTypes.size(); ++i) {
            TypePtr x = fieldInfoTypes[i];
            IdentifierPtr name;
            TypePtr type;
            if (!unpackField(x, name, type))
                argumentError(i, "each field should be a "
                              "tuple of (name,type)");
            t->fieldIndexMap[name->str] = i;
            t->fieldTypes.push_back(type);
            t->fieldNames.push_back(name);
        }
    }
    else {
        for (unsigned i = 0; i < body->fields.size(); ++i) {
            RecordField *x = body->fields[i].ptr();
            t->fieldIndexMap[x->name->str] = i;
            TypePtr ftype = evaluateType(x->type, env);
            t->fieldTypes.push_back(ftype);
            t->fieldNames.push_back(x->name);
        }
    }
}
Esempio n. 11
0
MatchResultPtr matchInvoke(OverloadPtr overload,
                           ObjectPtr callable,
                           llvm::ArrayRef<TypePtr> argsKey)
{
    initializePatterns(overload);

    PatternReseter reseter(overload);

    if (!unifyPatternObj(overload->callablePattern, callable))
        return new MatchCallableError(overload->target, callable);

    CodePtr code = overload->code;
    if (code->hasVarArg) {
        if (argsKey.size() < code->formalArgs.size()-1)
            return new MatchArityError(unsigned(code->formalArgs.size()), unsigned(argsKey.size()), true);
    }
    else {
        if (code->formalArgs.size() != argsKey.size())
            return new MatchArityError(unsigned(code->formalArgs.size()), unsigned(argsKey.size()), false);
    }
    llvm::ArrayRef<FormalArgPtr> formalArgs = code->formalArgs;
    unsigned varArgSize = unsigned(argsKey.size()-formalArgs.size()+1);
    for (unsigned i = 0, j = 0; i < formalArgs.size(); ++i) {
        FormalArgPtr x = formalArgs[i];
        if (x->varArg) {
            if (x->type.ptr()) {
                MultiStaticPtr types = new MultiStatic();
                for (; j < varArgSize; ++j)
                    types->add(argsKey[i+j].ptr());
                --j;
                MultiPatternPtr pattern = overload->varArgPattern;
                if (!unifyMulti(pattern, types))
                    return new MatchMultiArgumentError(unsigned(formalArgs.size()), types, x);                
            } else {
                j = varArgSize-1;
            }
        } else {
            if (x->type.ptr()) {
                PatternPtr pattern = overload->argPatterns[i];
                if (!unifyPatternObj(pattern, argsKey[i+j].ptr()))
                    return new MatchArgumentError(i+j, argsKey[i+j], x);
            }
        }
    }
    
    EnvPtr staticEnv = new Env(overload->env);
    llvm::ArrayRef<PatternVar> pvars = code->patternVars;
    for (size_t i = 0; i < pvars.size(); ++i) {
        if (pvars[i].isMulti) {
            MultiStaticPtr ms = derefDeep(overload->multiCells[i].ptr());
            if (!ms)
                error(pvars[i].name, "unbound pattern variable");
            addLocal(staticEnv, pvars[i].name, ms.ptr());
        }
        else {
            ObjectPtr v = derefDeep(overload->cells[i].ptr());
            if (!v)
                error(pvars[i].name, "unbound pattern variable");
            addLocal(staticEnv, pvars[i].name, v.ptr());
        }
    }

    reseter.reset();
    
    if (code->predicate.ptr())
        if (!evaluateBool(code->predicate, staticEnv))
            return new MatchPredicateError(code->predicate);

    MatchSuccessPtr result = new MatchSuccess(
        overload, staticEnv, callable, argsKey
    );

    for (unsigned i = 0, j = 0; i < formalArgs.size(); ++i) {
        FormalArgPtr x = formalArgs[i];
        if (x->varArg) {
            result->varArgName = x->name;
            result->varArgPosition = i;
            for (; j < varArgSize; ++j) {
                result->varArgTypes.push_back(argsKey[i+j]);
            }
            --j;
        } else {
            result->fixedArgNames.push_back(x->name);
            result->fixedArgTypes.push_back(argsKey[i+j]);
        }
    }
    if(!code->hasVarArg) result->varArgPosition = unsigned(result->fixedArgNames.size());
    return result.ptr();
}
Esempio n. 12
0
void convertFreeVars(ExprPtr &x, EnvPtr env, LambdaContext &ctx)
{
    switch (x->exprKind) {

    case BOOL_LITERAL :
    case INT_LITERAL :
    case FLOAT_LITERAL :
    case CHAR_LITERAL :
    case STRING_LITERAL :
    case IDENTIFIER_LITERAL :
        break;

    case NAME_REF : {
        NameRef *y = (NameRef *)x.ptr();
        bool isNonLocal = false;
        bool isGlobal = false;
        ObjectPtr z = lookupEnvEx(env, y->name, ctx.nonLocalEnv,
                                  isNonLocal, isGlobal);
        if (isNonLocal && !isGlobal) {
            if ((z->objKind == PVALUE) || (z->objKind == CVALUE)) {
                TypePtr t = typeOfValue(z);
                if (isStaticOrTupleOfStatics(t)) {
                    ExprListPtr args = new ExprList();
                    args->add(new ObjectExpr(t.ptr()));
                    CallPtr call = new Call(operator_expr_typeToRValue(), args);
                    call->location = y->location;
                    x = call.ptr();
                }
                else {
                    addFreeVar(ctx, y->name->str);
                    IdentifierPtr a = new Identifier(ctx.closureDataName);
                    a->location = y->location;
                    NameRefPtr b = new NameRef(a);
                    b->location = y->location;
                    FieldRefPtr c = new FieldRef(b.ptr(), y->name);
                    c->location = y->location;
                    if (ctx.captureByRef) {
                        vector<int> ops;
                        ops.push_back(DEREFERENCE);
                        ExprPtr d = new VariadicOp(ops, new ExprList(c.ptr()));
                        d->location = y->location;
                        x = d.ptr();
                    }
                    else {
                        x = c.ptr();
                    }
                }
            }
            else if ((z->objKind == MULTI_PVALUE) || (z->objKind == MULTI_CVALUE)) {
                vector<TypePtr> types = typesOfValues(z);
                bool allStatic = true;
                for (unsigned i = 0; i < types.size(); ++i) {
                    if (!isStaticOrTupleOfStatics(types[i])) {
                        allStatic = false;
                        break;
                    }
                }
                if (allStatic) {
                    ExprListPtr args = new ExprList();
                    for (unsigned i = 0; i < types.size(); ++i)
                        args->add(new ObjectExpr(types[i].ptr()));
                    CallPtr call = new Call(operator_expr_typesToRValues(), args);
                    call->location = y->location;
                    x = call.ptr();
                }
                else {
                    addFreeVar(ctx, y->name->str);
                    IdentifierPtr a = new Identifier(ctx.closureDataName);
                    a->location = y->location;
                    NameRefPtr b = new NameRef(a);
                    b->location = y->location;
                    FieldRefPtr c = new FieldRef(b.ptr(), y->name);
                    c->location = y->location;
                    if (ctx.captureByRef) {
                        ExprPtr f =
                            operator_expr_unpackMultiValuedFreeVarAndDereference();
                        CallPtr d = new Call(f, new ExprList());
                        d->parenArgs->add(c.ptr());
                        x = d.ptr();
                    }
                    else {
                        ExprPtr f = operator_expr_unpackMultiValuedFreeVar();
                        CallPtr d = new Call(f, new ExprList());
                        d->parenArgs->add(c.ptr());
                        x = d.ptr();
                    }
                }
            }
        }
        break;
    }

    case TUPLE : {
        Tuple *y = (Tuple *)x.ptr();
        convertFreeVars(y->args, env, ctx);
        break;
    }

    case PAREN : {
        Paren *y = (Paren *)x.ptr();
        convertFreeVars(y->args, env, ctx);
        break;
    }

    case INDEXING : {
        Indexing *y = (Indexing *)x.ptr();
        convertFreeVars(y->expr, env, ctx);
        convertFreeVars(y->args, env, ctx);
        break;
    }

    case CALL : {
        Call *y = (Call *)x.ptr();
        convertFreeVars(y->expr, env, ctx);
        convertFreeVars(y->parenArgs, env, ctx);
        convertFreeVars(y->lambdaArgs, env, ctx);
        break;
    }

    case FIELD_REF : {
        FieldRef *y = (FieldRef *)x.ptr();
        convertFreeVars(y->expr, env, ctx);
        break;
    }

    case STATIC_INDEXING : {
        StaticIndexing *y = (StaticIndexing *)x.ptr();
        convertFreeVars(y->expr, env, ctx);
        break;
    }

    case VARIADIC_OP : {
        VariadicOp *y = (VariadicOp *)x.ptr();
        convertFreeVars(y->exprs, env, ctx);
        break;
    }

    case AND : {
        And *y = (And *)x.ptr();
        convertFreeVars(y->expr1, env, ctx);
        convertFreeVars(y->expr2, env, ctx);
        break;
    }

    case OR : {
        Or *y = (Or *)x.ptr();
        convertFreeVars(y->expr1, env, ctx);
        convertFreeVars(y->expr2, env, ctx);
        break;
    }

    case LAMBDA : {
        Lambda *y = (Lambda *)x.ptr();
        EnvPtr env2 = new Env(env);
        for (unsigned i = 0; i < y->formalArgs.size(); ++i)
            addLocal(env2, y->formalArgs[i]->name, y->formalArgs[i]->name.ptr());
        if (y->formalVarArg.ptr())
            addLocal(env2, y->formalVarArg->name, y->formalVarArg->name.ptr());
        convertFreeVars(y->body, env2, ctx);
        break;
    }

    case UNPACK : {
        Unpack *y = (Unpack *)x.ptr();
        convertFreeVars(y->expr, env, ctx);
        break;
    }

    case STATIC_EXPR : {
        StaticExpr *y = (StaticExpr *)x.ptr();
        convertFreeVars(y->expr, env, ctx);
        break;
    }

    case DISPATCH_EXPR : {
        DispatchExpr *y = (DispatchExpr *)x.ptr();
        convertFreeVars(y->expr, env, ctx);
        break;
    }

    case EVAL_EXPR : {
        EvalExpr *eval = (EvalExpr *)x.ptr();
        convertFreeVars(eval->args, env, ctx);
        break;
    }

    case FOREIGN_EXPR :
    case OBJECT_EXPR :
    case FILE_EXPR :
    case LINE_EXPR :
    case COLUMN_EXPR :
    case ARG_EXPR :
        break;
    }
}
Esempio n. 13
0
void convertFreeVars(StatementPtr x, EnvPtr env, LambdaContext &ctx)
{
    switch (x->stmtKind) {

    case BLOCK : {
        Block *y = (Block *)x.ptr();
        if (!y->desugared)
            y->desugared = desugarBlock(y);
        for (unsigned i = 0; i < y->desugared->statements.size(); ++i) {
            StatementPtr z = y->desugared->statements[i];
            if (z->stmtKind == BINDING) {
                Binding *a = (Binding *)z.ptr();
                convertFreeVars(a->values, env, ctx);
                EnvPtr env2 = new Env(env);
                for (unsigned j = 0; j < a->names.size(); ++j)
                    addLocal(env2, a->names[j], a->names[j].ptr());
                env = env2;
            }
            else {
                convertFreeVars(z, env, ctx);
            }
        }
        break;
    }

    case LABEL :
    case BINDING : {
        break;
    }

    case ASSIGNMENT : {
        Assignment *y = (Assignment *)x.ptr();
        convertFreeVars(y->left, env, ctx);
        convertFreeVars(y->right, env, ctx);
        break;
    }

    case INIT_ASSIGNMENT : {
        InitAssignment *y = (InitAssignment *)x.ptr();
        convertFreeVars(y->left, env, ctx);
        convertFreeVars(y->right, env, ctx);
        break;
    }

    case UPDATE_ASSIGNMENT : {
        UpdateAssignment *y = (UpdateAssignment *)x.ptr();
        convertFreeVars(y->left, env, ctx);
        convertFreeVars(y->right, env, ctx);
        break;
    }

    case GOTO : {
        break;
    }

    case RETURN : {
        Return *y = (Return *)x.ptr();
        convertFreeVars(y->values, env, ctx);
        break;
    }

    case IF : {
        If *y = (If *)x.ptr();
        convertFreeVars(y->condition, env, ctx);
        convertFreeVars(y->thenPart, env, ctx);
        if (y->elsePart.ptr())
            convertFreeVars(y->elsePart, env, ctx);
        break;
    }

    case SWITCH : {
        Switch *y = (Switch *)x.ptr();
        convertFreeVars(y->expr, env, ctx);
        for (unsigned i = 0; i < y->caseBlocks.size(); ++i) {
            CaseBlockPtr z = y->caseBlocks[i];
            convertFreeVars(z->caseLabels, env, ctx);
            convertFreeVars(z->body, env, ctx);
        }
        if (y->defaultCase.ptr())
            convertFreeVars(y->defaultCase, env, ctx);
        break;
    }

    case EVAL_STATEMENT : {
        EvalStatement *eval = (EvalStatement *)x.ptr();
        convertFreeVars(eval->args, env, ctx);
        break;
    }

    case EXPR_STATEMENT : {
        ExprStatement *y = (ExprStatement *)x.ptr();
        convertFreeVars(y->expr, env, ctx);
        break;
    }

    case WHILE : {
        While *y = (While *)x.ptr();
        convertFreeVars(y->condition, env, ctx);
        convertFreeVars(y->body, env, ctx);
        break;
    }

    case BREAK :
    case CONTINUE : {
        break;
    }

    case FOR : {
        For *y = (For *)x.ptr();
        convertFreeVars(y->expr, env, ctx);
        EnvPtr env2 = new Env(env);
        for (unsigned j = 0; j < y->variables.size(); ++j)
            addLocal(env2, y->variables[j], y->variables[j].ptr());
        convertFreeVars(y->body, env2, ctx);
        break;
    }

    case FOREIGN_STATEMENT : {
        break;
    }

    case TRY : {
        Try *y = (Try *)x.ptr();
        convertFreeVars(y->tryBlock, env, ctx);
        for (unsigned i = 0; i < y->catchBlocks.size(); ++i) {
            EnvPtr env2 = new Env(env);
            addLocal(env2,
                y->catchBlocks[i]->exceptionVar,
                y->catchBlocks[i]->exceptionVar.ptr()
            );
            if (y->catchBlocks[i]->exceptionType.ptr())
                convertFreeVars(y->catchBlocks[i]->exceptionType, env, ctx);
            convertFreeVars(y->catchBlocks[i]->body, env2, ctx);
        }

        break;
    }

    case THROW : {
        Throw *y = (Throw *)x.ptr();
        convertFreeVars(y->expr, env, ctx);
        break;
    }

    case STATIC_FOR : {
        StaticFor *y = (StaticFor *)x.ptr();
        convertFreeVars(y->values, env, ctx);
        EnvPtr env2 = new Env(env);
        addLocal(env2, y->variable, y->variable.ptr());
        convertFreeVars(y->body, env2, ctx);
        break;
    }

    case FINALLY : {
        Finally *y = (Finally *)x.ptr();
        convertFreeVars(y->body, env, ctx);
        break;
    }

    case ONERROR : {
        OnError *y = (OnError *)x.ptr();
        convertFreeVars(y->body, env, ctx);
        break;
    }

    case UNREACHABLE :
        break;

    default :
        assert(false);

    }
}
Esempio n. 14
0
MatchResultPtr matchInvoke(OverloadPtr overload,
                           ObjectPtr callable,
                           const vector<TypePtr> &argsKey)
{
    initializePatterns(overload);

    PatternReseter reseter(overload);

    if (!unifyPatternObj(overload->callablePattern, callable))
        return new MatchCallableError(overload->target, callable);

    CodePtr code = overload->code;
    if (code->formalVarArg.ptr()) {
        if (argsKey.size() < code->formalArgs.size())
            return new MatchArityError(code->formalArgs.size(), argsKey.size(), true);
    }
    else {
        if (code->formalArgs.size() != argsKey.size())
            return new MatchArityError(code->formalArgs.size(), argsKey.size(), false);
    }

    const vector<FormalArgPtr> &formalArgs = code->formalArgs;
    for (unsigned i = 0; i < formalArgs.size(); ++i) {
        FormalArgPtr x = formalArgs[i];
        if (x->type.ptr()) {
            PatternPtr pattern = overload->argPatterns[i];
            if (!unifyPatternObj(pattern, argsKey[i].ptr()))
                return new MatchArgumentError(i, argsKey[i], x);
        }
    }
    if (code->formalVarArg.ptr() && code->formalVarArg->type.ptr()) {
        MultiStaticPtr types = new MultiStatic();
        for (unsigned i = formalArgs.size(); i < argsKey.size(); ++i)
            types->add(argsKey[i].ptr());
        if (!unifyMulti(overload->varArgPattern, types))
            return new MatchMultiArgumentError(formalArgs.size(), types, code->formalVarArg);
    }

    EnvPtr staticEnv = new Env(overload->env);
    const vector<PatternVar> &pvars = code->patternVars;
    for (unsigned i = 0; i < pvars.size(); ++i) {
        if (pvars[i].isMulti) {
            MultiStaticPtr ms = derefDeep(overload->multiCells[i].ptr());
            if (!ms)
                error(pvars[i].name, "unbound pattern variable");
            addLocal(staticEnv, pvars[i].name, ms.ptr());
        }
        else {
            ObjectPtr v = derefDeep(overload->cells[i].ptr());
            if (!v)
                error(pvars[i].name, "unbound pattern variable");
            addLocal(staticEnv, pvars[i].name, v.ptr());
        }
    }

    reseter.reset();
    
    if (code->predicate.ptr()) {
        if (!evaluateBool(code->predicate, staticEnv))
            return new MatchPredicateError(code->predicate);
    }

    MatchSuccessPtr result = new MatchSuccess(
        overload->callByName, overload->isInline, code, staticEnv,
        callable, argsKey
    );
    for (unsigned i = 0; i < formalArgs.size(); ++i) {
        FormalArgPtr x = formalArgs[i];
        result->fixedArgNames.push_back(x->name);
        result->fixedArgTypes.push_back(argsKey[i]);
    }
    if (code->formalVarArg.ptr()) {
        result->varArgName = code->formalVarArg->name;
        for (unsigned i = formalArgs.size(); i < argsKey.size(); ++i) {
            result->varArgTypes.push_back(argsKey[i]);
        }
    }
    return result.ptr();
}