Commit 1b012805 authored by Kevin Modzelewski's avatar Kevin Modzelewski

str.replace

Also had to fix some bugs with codegen function types --
not sure how those snuck through
parent 7062e5b2
......@@ -455,7 +455,8 @@ static ConcreteCompilerVariable* _call(IREmitter& emitter, const OpInfo& info, l
}
llvm_args.push_back(arg_array);
llvm_args.push_back(embedConstantPtr(keyword_names, g.vector_ptr));
if (pass_keyword_names)
llvm_args.push_back(embedConstantPtr(keyword_names, g.vector_ptr));
} else if (pass_keyword_names) {
llvm_args.push_back(embedConstantPtr(NULL, g.llvm_value_type_ptr->getPointerTo()));
llvm_args.push_back(embedConstantPtr(keyword_names, g.vector_ptr));
......@@ -487,11 +488,14 @@ static ConcreteCompilerVariable* _call(IREmitter& emitter, const OpInfo& info, l
->getReturnType() == g.llvm_value_type_ptr);
rtn = emitter.getBuilder()->CreateIntToPtr(uncasted, g.llvm_value_type_ptr);
} else {
// printf("\n");
// func->dump();
// printf("\n");
// for (auto a : llvm_args) {
// a->dump();
//}
// printf("%ld %ld\n", llvm_args.size(), args.size());
// printf("\n");
rtn = emitter.createCall(info.exc_info, func, llvm_args).getInstruction();
}
......@@ -527,7 +531,7 @@ CompilerVariable* UnknownType::call(IREmitter& emitter, const OpInfo& info, Conc
else if (npassed_args == 3)
func = g.funcs.runtimeCall3;
else
func = g.funcs.runtimeCall;
func = g.funcs.runtimeCallN;
std::vector<llvm::Value*> other_args;
other_args.push_back(var->getValue());
......@@ -556,7 +560,7 @@ CompilerVariable* UnknownType::callattr(IREmitter& emitter, const OpInfo& info,
else if (npassed_args == 3)
func = g.funcs.callattr3;
else
func = g.funcs.callattr;
func = g.funcs.callattrN;
std::vector<llvm::Value*> other_args;
other_args.push_back(var->getValue());
......@@ -1346,10 +1350,11 @@ public:
// TODO support passing unboxed values as arguments
assert(cf->spec->arg_types[i]->llvmType() == g.llvm_value_type_ptr);
arg_types.push_back(g.llvm_value_type_ptr);
if (i == 3) {
arg_types.push_back(g.llvm_value_type_ptr->getPointerTo());
break;
} else {
arg_types.push_back(g.llvm_value_type_ptr);
}
}
llvm::FunctionType* ft = llvm::FunctionType::get(cf->spec->rtn_type->llvmType(), arg_types, false);
......
......@@ -218,6 +218,9 @@ void initGlobalFuncs(GlobalState& g) {
g.llvm_value_type_ptr, g.llvm_value_type_ptr);
g.funcs.runtimeCall3 = addFunc((void*)runtimeCall, g.llvm_value_type_ptr, g.llvm_value_type_ptr, g.i32,
g.llvm_value_type_ptr, g.llvm_value_type_ptr, g.llvm_value_type_ptr);
g.funcs.runtimeCallN
= addFunc((void*)runtimeCall, g.llvm_value_type_ptr, g.llvm_value_type_ptr, g.i32, g.llvm_value_type_ptr,
g.llvm_value_type_ptr, g.llvm_value_type_ptr, g.llvm_value_type_ptr->getPointerTo());
g.funcs.callattr = getFunc((void*)callattr, "callattr");
g.funcs.callattr0
......@@ -228,6 +231,9 @@ void initGlobalFuncs(GlobalState& g) {
g.i1, g.i32, g.llvm_value_type_ptr, g.llvm_value_type_ptr);
g.funcs.callattr3 = addFunc((void*)callattr, g.llvm_value_type_ptr, g.llvm_value_type_ptr, g.llvm_str_type_ptr,
g.i1, g.i32, g.llvm_value_type_ptr, g.llvm_value_type_ptr, g.llvm_value_type_ptr);
g.funcs.callattrN = addFunc((void*)callattr, g.llvm_value_type_ptr, g.llvm_value_type_ptr, g.llvm_str_type_ptr,
g.i1, g.i32, g.llvm_value_type_ptr, g.llvm_value_type_ptr, g.llvm_value_type_ptr,
g.llvm_value_type_ptr->getPointerTo());
g.funcs.reoptCompiledFunc = addFunc((void*)reoptCompiledFunc, g.i8_ptr, g.i8_ptr);
g.funcs.compilePartialFunc = addFunc((void*)compilePartialFunc, g.i8_ptr, g.i8_ptr);
......
......@@ -42,8 +42,8 @@ struct GlobalFuncs {
llvm::Value* unpackIntoArray, *raiseAttributeError, *raiseAttributeErrorStr, *raiseNotIterableError,
*assertNameDefined, *assertFail;
llvm::Value* printFloat, *listAppendInternal;
llvm::Value* runtimeCall0, *runtimeCall1, *runtimeCall2, *runtimeCall3, *runtimeCall;
llvm::Value* callattr0, *callattr1, *callattr2, *callattr3, *callattr;
llvm::Value* runtimeCall0, *runtimeCall1, *runtimeCall2, *runtimeCall3, *runtimeCall, *runtimeCallN;
llvm::Value* callattr0, *callattr1, *callattr2, *callattr3, *callattr, *callattrN;
llvm::Value* reoptCompiledFunc, *compilePartialFunc;
llvm::Value* __cxa_begin_catch, *__cxa_end_catch;
......
......@@ -580,6 +580,33 @@ Box* strJoin(BoxedString* self, Box* rhs) {
}
}
Box* strReplace(Box* _self, Box* _old, Box* _new, Box** _args) {
RELEASE_ASSERT(_self->cls == str_cls, "");
BoxedString* self = static_cast<BoxedString*>(_self);
RELEASE_ASSERT(_old->cls == str_cls, "");
BoxedString* old = static_cast<BoxedString*>(_old);
RELEASE_ASSERT(_new->cls == str_cls, "");
BoxedString* new_ = static_cast<BoxedString*>(_new);
Box* _count = _args[0];
RELEASE_ASSERT(_count->cls == int_cls, "an integer is required");
BoxedInt* count = static_cast<BoxedInt*>(_count);
RELEASE_ASSERT(count->n < 0, "'count' argument unsupported");
BoxedString* rtn = new BoxedString(self->s);
// From http://stackoverflow.com/questions/2896600/how-to-replace-all-occurrences-of-a-character-in-string
size_t start_pos = 0;
while ((start_pos = rtn->s.find(old->s, start_pos)) != std::string::npos) {
rtn->s.replace(start_pos, old->s.length(), new_->s);
start_pos += new_->s.length(); // Handles case where 'to' is a substring of 'from'
}
return rtn;
}
Box* strSplit(BoxedString* self, BoxedString* sep, BoxedInt* _max_split) {
assert(self->cls == str_cls);
if (_max_split->cls != int_cls)
......@@ -1029,6 +1056,9 @@ void setupStr() {
str_cls->giveAttr("join", new BoxedFunction(boxRTFunction((void*)strJoin, STR, 2)));
str_cls->giveAttr("replace",
new BoxedFunction(boxRTFunction((void*)strReplace, STR, 4, 1, false, false), { boxInt(-1) }));
str_cls->giveAttr(
"split", new BoxedFunction(boxRTFunction((void*)strSplit, LIST, 3, 2, false, false), { None, boxInt(-1) }));
str_cls->giveAttr(
......
......@@ -60,3 +60,5 @@ for i in xrange(-3, 5):
for i in ["", "a", "ab", "aa"]:
for j in ["", "b", "a", "ab", "aa"]:
print i, j, i.startswith(j), j.startswith(i), i.endswith(j), j.endswith(i), i.find(j), j.find(i), i.rfind(j), j.rfind(i)
print "bananananananas".replace("anan", "an")
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment