bool isStaticOrTupleOfStatics(TypePtr t) { switch (t->typeKind) { case STATIC_TYPE : return true; case TUPLE_TYPE : { TupleType *tt = (TupleType *)t.ptr(); for (unsigned i = 0; i < tt->elementTypes.size(); ++i) { if (!isStaticOrTupleOfStatics(tt->elementTypes[i])) return false; } return true; } default : return false; } }
void printName(llvm::raw_ostream &out, ObjectPtr x) { switch (x->objKind) { case IDENTIFIER : { Identifier *y = (Identifier *)x.ptr(); if (_safeNames > 0) { out << "#"; for (unsigned i = 0; i < y->str.size(); ++i) { char ch = y->str[i]; if (isSafe(ch)) out << ch; else out << 'c' << (unsigned int)ch; } } else { out << "\""; for (unsigned i = 0; i < y->str.size(); ++i) { char ch = y->str[i]; switch (ch) { case '\0': out << "\\0"; break; case '\n': out << "\\n"; break; case '\r': out << "\\r"; break; case '\t': out << "\\t"; break; case '\f': out << "\\f"; break; case '\\': out << "\\\\"; break; case '\'': out << "\\'"; break; case '\"': out << "\\\""; break; default: if (ch >= '\x20' && ch <= '\x7E') out << ch; else { out << "\\x"; if (ch < 16) out << '0'; out.write_hex((unsigned long long int)ch); } break; } } out << "\""; } break; } case GLOBAL_VARIABLE : { GlobalVariable *y = (GlobalVariable *)x.ptr(); out << y->name->str; break; } case GLOBAL_ALIAS : { GlobalAlias *y = (GlobalAlias *)x.ptr(); out << y->name->str; break; } case RECORD_DECL : { RecordDecl *y = (RecordDecl *)x.ptr(); out << y->name->str; break; } case VARIANT_DECL : { VariantDecl *y = (VariantDecl *)x.ptr(); out << y->name->str; break; } case PROCEDURE : { Procedure *y = (Procedure *)x.ptr(); out << y->name->str; break; } case MODULE : { Module *m = (Module *)x.ptr(); out << m->moduleName; break; } case INTRINSIC : { IntrinsicSymbol *intrin = (IntrinsicSymbol *)x.ptr(); out << intrin->name->str; break; } case PRIM_OP : { out << primOpName((PrimOp *)x.ptr()); break; } case TYPE : { typePrint(out, (Type *)x.ptr()); break; } case VALUE_HOLDER : { ValueHolder *y = (ValueHolder *)x.ptr(); if (isStaticOrTupleOfStatics(y->type)) { printStaticOrTupleOfStatics(out, y->type); } else { EValuePtr ev = new EValue(y->type, y->buf); printValue(out, ev); } break; } case EXTERNAL_PROCEDURE : { ExternalProcedure *proc = (ExternalProcedure*)x.ptr(); out << "external " << proc->name->str; break; } default : { out << "UnknownNamedObject(" << x->objKind << ")"; break; } } }
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; } }