ExprPtr desugarVariadicOp(VariadicOpPtr x, CompilerState* cst) { ExprPtr callable = lookupCallable(x->op, cst); CallPtr call = new Call(callable, new ExprList()); call->parenArgs->add(x->exprs); call->location = x->location; return call.ptr(); }
ExprPtr desugarStaticIndexing(StaticIndexingPtr x, CompilerState* cst) { ExprListPtr args = new ExprList(x->expr); ValueHolderPtr vh = sizeTToValueHolder(x->index, cst); args->add(new StaticExpr(new ObjectExpr(vh.ptr()))); CallPtr call = new Call(operator_expr_staticIndex(cst), args); call->location = x->location; return call.ptr(); }
ExprPtr desugarCharLiteral(char c, CompilerState* cst) { ExprPtr nameRef = operator_expr_charLiteral(cst); CallPtr call = new Call(nameRef, new ExprList()); llvm::SmallString<128> buf; llvm::raw_svector_ostream out(buf); out << (int)c; call->parenArgs->add(new IntLiteral(out.str(), "ss")); return call.ptr(); }
void desugarFieldRef(FieldRefPtr x, ModulePtr module) { if (x->expr->exprKind == FIELD_REF || x->expr->exprKind == NAME_REF) { ModulePtr m = dottedImportedModule(x.ptr(), module.ptr()); if (m.ptr()) { x->isDottedModuleName = true; x->desugared = new ObjectExpr(m.ptr()); return; } } ExprListPtr args = new ExprList(x->expr); args->add(new ObjectExpr(x->name.ptr())); CallPtr call = new Call(operator_expr_fieldRef(module->cst), args); call->location = x->location; x->desugared = call.ptr(); }
StatementPtr desugarForStatement(ForPtr x, CompilerState* cst) { IdentifierPtr exprVar = Identifier::get("%expr", x->location); IdentifierPtr iterVar = Identifier::get("%iter", x->location); IdentifierPtr valueVar = Identifier::get("%value", x->location); BlockPtr block = new Block(); block->location = x->body->location; vector<StatementPtr> &bs = block->statements; BindingPtr exprBinding = new Binding(FORWARD, identV(exprVar), new ExprList(x->expr)); exprBinding->location = x->body->location; bs.push_back(exprBinding.ptr()); CallPtr iteratorCall = new Call(operator_expr_iterator(cst), new ExprList()); iteratorCall->location = x->body->location; ExprPtr exprName = new NameRef(exprVar); exprName->location = x->location; iteratorCall->parenArgs->add(exprName); BindingPtr iteratorBinding = new Binding(FORWARD, identV(iterVar), new ExprList(iteratorCall.ptr())); iteratorBinding->location = x->body->location; bs.push_back(iteratorBinding.ptr()); vector<StatementPtr> valueStatements; CallPtr nextValueCall = new Call(operator_expr_nextValue(cst), new ExprList()); nextValueCall->location = x->body->location; ExprPtr iterName = new NameRef(iterVar); iterName->location = x->body->location; nextValueCall->parenArgs->add(iterName); BindingPtr nextValueBinding = new Binding(VAR, identV(valueVar), new ExprList(nextValueCall.ptr())); nextValueBinding->location = x->body->location; valueStatements.push_back(nextValueBinding.ptr()); CallPtr hasValueCall = new Call(operator_expr_hasValueP(cst), new ExprList()); hasValueCall->location = x->body->location; ExprPtr valueName = new NameRef(valueVar); valueName->location = x->body->location; hasValueCall->parenArgs->add(valueName); CallPtr getValueCall = new Call(operator_expr_getValue(cst), new ExprList()); getValueCall->location = x->body->location; getValueCall->parenArgs->add(valueName); BlockPtr whileBody = new Block(); whileBody->location = x->body->location; vector<StatementPtr> &ws = whileBody->statements; ws.push_back(new Binding(FORWARD, identVtoFormalV(x->variables), new ExprList(getValueCall.ptr()))); ws.push_back(x->body); StatementPtr whileStmt = new While(valueStatements, hasValueCall.ptr(), whileBody.ptr()); whileStmt->location = x->location; bs.push_back(whileStmt); return block.ptr(); }
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; } }
static void initializeLambdaWithFreeVars(LambdaPtr x, EnvPtr env, string const &closureDataName, string const &lname) { RecordPtr r = new Record(PRIVATE); r->location = x->location; r->name = new Identifier(lname); r->env = env; x->lambdaRecord = r; r->lambda = x; vector<RecordFieldPtr> fields; CallPtr converted = new Call(NULL, new ExprList()); for (unsigned i = 0; i < x->freeVars.size(); ++i) { IdentifierPtr ident = new Identifier(x->freeVars[i]); NameRefPtr nameRef = new NameRef(ident); TypePtr type; ObjectPtr obj = safeLookupEnv(env, ident); switch (obj->objKind) { case PVALUE : case CVALUE : { type = typeOfValue(obj); if (x->captureByRef) { type = pointerType(type); vector<int> ops; ops.push_back(ADDRESS_OF); ExprPtr addr = new VariadicOp(ops, new ExprList(nameRef.ptr())); converted->parenArgs->add(addr); } else { converted->parenArgs->add(nameRef.ptr()); } break; } case MULTI_PVALUE : case MULTI_CVALUE : { vector<TypePtr> types = typesOfValues(obj); vector<TypePtr> elementTypes; for (unsigned j = 0; j < types.size(); ++j) { TypePtr t = types[j]; if (x->captureByRef) t = pointerType(t); elementTypes.push_back(t); } type = tupleType(elementTypes); if (x->captureByRef) { ExprPtr e = operator_expr_packMultiValuedFreeVarByRef(); CallPtr call = new Call(e, new ExprList()); call->parenArgs->add(new Unpack(nameRef.ptr())); converted->parenArgs->add(call.ptr()); } else { ExprPtr e = operator_expr_packMultiValuedFreeVar(); CallPtr call = new Call(e, new ExprList()); call->parenArgs->add(new Unpack(nameRef.ptr())); converted->parenArgs->add(call.ptr()); } break; } default : assert(false); } ExprPtr fieldType = new ObjectExpr(type.ptr()); RecordFieldPtr field = new RecordField(ident, fieldType); fields.push_back(field); } r->body = new RecordBody(fields); TypePtr t = recordType(r, vector<ObjectPtr>()); x->lambdaType = t; ExprPtr typeExpr = new ObjectExpr(t.ptr()); converted->expr = typeExpr; x->converted = converted.ptr(); CodePtr code = new Code(); code->location = x->location; IdentifierPtr closureDataIdent = new Identifier(closureDataName); FormalArgPtr closureDataArg = new FormalArg(closureDataIdent, typeExpr); code->formalArgs.push_back(closureDataArg.ptr()); for (unsigned i = 0; i < x->formalArgs.size(); ++i) { code->formalArgs.push_back(x->formalArgs[i]); } if (x->formalVarArg.ptr()) { code->formalVarArg = x->formalVarArg; } code->body = x->body; OverloadPtr overload = new Overload( operator_expr_call(), code, false, false ); overload->env = env; overload->location = x->location; ObjectPtr obj = operator_call(); if (obj->objKind != PROCEDURE) error("'call' operator not found!"); Procedure *callObj = (Procedure *)obj.ptr(); callObj->overloads.insert(callObj->overloads.begin(), overload); }
OverloadPtr desugarAsOverload(OverloadPtr &x, CompilerState* cst) { assert(x->hasAsConversion); //Generate specialised overload CodePtr code = new Code(); code->location = x->location; clone(x->code->patternVars, code->patternVars); //Generate stub body CallPtr returnExpr = new Call(x->target.ptr(), new ExprList()); returnExpr->location = x->code->body->location; //Add patterns as static args for (unsigned i = 0; i < x->code->patternVars.size(); ++i) { llvm::SmallString<128> buf; llvm::raw_svector_ostream sout(buf); sout << "%asArg" << i; IdentifierPtr argName = Identifier::get(sout.str()); ExprPtr staticName = new ForeignExpr("prelude", new NameRef(Identifier::get("Static"))); IndexingPtr indexing = new Indexing(staticName, new ExprList(new NameRef(x->code->patternVars[i].name))); indexing->startLocation = code->patternVars[i].name->location; indexing->endLocation = code->patternVars[i].name->location; FormalArgPtr arg = new FormalArg(argName, indexing.ptr()); arg->location = x->code->patternVars[i].name->location; code->formalArgs.insert(code->formalArgs.begin(), arg); //Add patterns as static call args ExprPtr callArg = new NameRef(x->code->patternVars[i].name); returnExpr->parenArgs->add(callArg); } //Add args for (unsigned i = 0; i < x->code->formalArgs.size(); ++i) { FormalArgPtr arg = clone(x->code->formalArgs[i]); arg->tempness = TEMPNESS_FORWARD; if (x->code->formalArgs[i]->asArg) { arg->type = x->code->formalArgs[i]->asType; ExprPtr typeArg = x->code->formalArgs[i]->asType; CallPtr callArg = new Call(operator_expr_asExpression(cst), new ExprList()); callArg->parenArgs->add(new NameRef(x->code->formalArgs[i]->name)); callArg->parenArgs->add(x->code->formalArgs[i]->asType); callArg->location = x->code->formalArgs[i]->location; returnExpr->parenArgs->add(callArg.ptr()); } else { ExprPtr arg0 = new NameRef(x->code->formalArgs[i]->name); arg0->location = x->code->formalArgs[i]->location; returnExpr->parenArgs->add(arg0); } code->formalArgs.push_back(arg.ptr()); } code->body = x->code->body; OverloadPtr spec = new Overload(x->module, x->target, code, x->callByName, x->isInline); spec->location = x->location; spec->env = x->env; x->code->body = new Return(RETURN_FORWARD, new ExprList(new Unpack(returnExpr.ptr())), true); x->isInline = FORCE_INLINE; return spec; }
StatementPtr desugarCatchBlocks(llvm::ArrayRef<CatchPtr> catchBlocks, CompilerState* cst) { assert(!catchBlocks.empty()); Location firstCatchLocation = catchBlocks.front()->location; IdentifierPtr expVar = Identifier::get("%exp", firstCatchLocation); CallPtr activeException = new Call(primitive_expr_activeException(cst), new ExprList()); activeException->location = firstCatchLocation; BindingPtr expBinding = new Binding(VAR, identVtoFormalV(vector<IdentifierPtr>(1, expVar)), new ExprList(activeException.ptr())); expBinding->location = firstCatchLocation; bool lastWasAny = false; IfPtr lastIf; StatementPtr result; for (size_t i = 0; i < catchBlocks.size(); ++i) { CatchPtr x = catchBlocks[i]; if (lastWasAny) error(x, "unreachable catch block"); if (x->exceptionType.ptr()) { ExprListPtr asTypeArgs = new ExprList(x->exceptionType); ExprPtr expVarName = new NameRef(expVar); expVarName->location = x->exceptionVar->location; asTypeArgs->add(expVarName); CallPtr cond = new Call(operator_expr_exceptionIsP(cst), asTypeArgs); cond->location = x->exceptionType->location; BlockPtr block = new Block(); block->location = x->location; vector<IdentifierPtr> identifiers; makeExceptionVars(identifiers, x); CallPtr getter = new Call(operator_expr_exceptionAs(cst), asTypeArgs); getter->location = x->exceptionVar->location; BindingPtr binding = new Binding(VAR, identVtoFormalV(identifiers), new ExprList(getter.ptr())); binding->location = x->exceptionVar->location; BindingPtr exceptionVarForRethrow = new Binding(REF, identVtoFormalV(vector<IdentifierPtr>(1, Identifier::get("%exception", x->location))), new ExprList(new NameRef(Identifier::get(x->exceptionVar->str, x->location)))); exceptionVarForRethrow->location = x->exceptionVar->location; block->statements.push_back(binding.ptr()); block->statements.push_back(exceptionVarForRethrow.ptr()); block->statements.push_back(x->body); IfPtr ifStatement = new If(cond.ptr(), block.ptr()); ifStatement->location = x->location; if (!result) result = ifStatement.ptr(); if (lastIf.ptr()) lastIf->elsePart = ifStatement.ptr(); lastIf = ifStatement; } else { BlockPtr block = new Block(); block->location = x->location; vector<IdentifierPtr> identifiers; makeExceptionVars(identifiers, x); ExprListPtr asAnyArgs = new ExprList(new NameRef(expVar)); CallPtr getter = new Call(operator_expr_exceptionAsAny(cst), asAnyArgs); getter->location = x->exceptionVar->location; BindingPtr binding = new Binding(VAR, identVtoFormalV(identifiers), new ExprList(getter.ptr())); binding->location = x->exceptionVar->location; BindingPtr exceptionVarForRethrow = new Binding(REF, identVtoFormalV(vector<IdentifierPtr>(1, Identifier::get("%exception", x->location))), new ExprList(new NameRef(Identifier::get(x->exceptionVar->str, x->location)))); exceptionVarForRethrow->location = x->exceptionVar->location; block->statements.push_back(binding.ptr()); block->statements.push_back(exceptionVarForRethrow.ptr()); block->statements.push_back(x->body); if (!result) result = block.ptr(); if (lastIf.ptr()) lastIf->elsePart = block.ptr(); lastWasAny = true; lastIf = NULL; } } assert(result.ptr()); if (!lastWasAny) { assert(lastIf.ptr()); BlockPtr block = new Block(); block->location = firstCatchLocation; ExprPtr expVarName = new NameRef(expVar); expVarName->location = firstCatchLocation; ExprListPtr continueArgs = new ExprList(expVarName); CallPtr continueException = new Call(operator_expr_continueException(cst), continueArgs); continueException->location = firstCatchLocation; StatementPtr stmt = new ExprStatement(continueException.ptr()); stmt->location = firstCatchLocation; block->statements.push_back(stmt); block->statements.push_back(new Unreachable()); lastIf->elsePart = block.ptr(); } BlockPtr block = new Block(); block->location = firstCatchLocation; block->statements.push_back(expBinding.ptr()); block->statements.push_back(result.ptr()); return block.ptr(); }