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,6 +455,7 @@ static ConcreteCompilerVariable* _call(IREmitter& emitter, const OpInfo& info, l ...@@ -455,6 +455,7 @@ static ConcreteCompilerVariable* _call(IREmitter& emitter, const OpInfo& info, l
} }
llvm_args.push_back(arg_array); llvm_args.push_back(arg_array);
if (pass_keyword_names)
llvm_args.push_back(embedConstantPtr(keyword_names, g.vector_ptr)); llvm_args.push_back(embedConstantPtr(keyword_names, g.vector_ptr));
} else if (pass_keyword_names) { } else if (pass_keyword_names) {
llvm_args.push_back(embedConstantPtr(NULL, g.llvm_value_type_ptr->getPointerTo())); llvm_args.push_back(embedConstantPtr(NULL, g.llvm_value_type_ptr->getPointerTo()));
...@@ -487,11 +488,14 @@ static ConcreteCompilerVariable* _call(IREmitter& emitter, const OpInfo& info, l ...@@ -487,11 +488,14 @@ static ConcreteCompilerVariable* _call(IREmitter& emitter, const OpInfo& info, l
->getReturnType() == g.llvm_value_type_ptr); ->getReturnType() == g.llvm_value_type_ptr);
rtn = emitter.getBuilder()->CreateIntToPtr(uncasted, g.llvm_value_type_ptr); rtn = emitter.getBuilder()->CreateIntToPtr(uncasted, g.llvm_value_type_ptr);
} else { } else {
// printf("\n");
// func->dump(); // func->dump();
// printf("\n");
// for (auto a : llvm_args) { // for (auto a : llvm_args) {
// a->dump(); // a->dump();
//} //}
// printf("%ld %ld\n", llvm_args.size(), args.size()); // printf("%ld %ld\n", llvm_args.size(), args.size());
// printf("\n");
rtn = emitter.createCall(info.exc_info, func, llvm_args).getInstruction(); rtn = emitter.createCall(info.exc_info, func, llvm_args).getInstruction();
} }
...@@ -527,7 +531,7 @@ CompilerVariable* UnknownType::call(IREmitter& emitter, const OpInfo& info, Conc ...@@ -527,7 +531,7 @@ CompilerVariable* UnknownType::call(IREmitter& emitter, const OpInfo& info, Conc
else if (npassed_args == 3) else if (npassed_args == 3)
func = g.funcs.runtimeCall3; func = g.funcs.runtimeCall3;
else else
func = g.funcs.runtimeCall; func = g.funcs.runtimeCallN;
std::vector<llvm::Value*> other_args; std::vector<llvm::Value*> other_args;
other_args.push_back(var->getValue()); other_args.push_back(var->getValue());
...@@ -556,7 +560,7 @@ CompilerVariable* UnknownType::callattr(IREmitter& emitter, const OpInfo& info, ...@@ -556,7 +560,7 @@ CompilerVariable* UnknownType::callattr(IREmitter& emitter, const OpInfo& info,
else if (npassed_args == 3) else if (npassed_args == 3)
func = g.funcs.callattr3; func = g.funcs.callattr3;
else else
func = g.funcs.callattr; func = g.funcs.callattrN;
std::vector<llvm::Value*> other_args; std::vector<llvm::Value*> other_args;
other_args.push_back(var->getValue()); other_args.push_back(var->getValue());
...@@ -1346,10 +1350,11 @@ public: ...@@ -1346,10 +1350,11 @@ public:
// TODO support passing unboxed values as arguments // TODO support passing unboxed values as arguments
assert(cf->spec->arg_types[i]->llvmType() == g.llvm_value_type_ptr); assert(cf->spec->arg_types[i]->llvmType() == g.llvm_value_type_ptr);
arg_types.push_back(g.llvm_value_type_ptr);
if (i == 3) { if (i == 3) {
arg_types.push_back(g.llvm_value_type_ptr->getPointerTo()); arg_types.push_back(g.llvm_value_type_ptr->getPointerTo());
break; 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); llvm::FunctionType* ft = llvm::FunctionType::get(cf->spec->rtn_type->llvmType(), arg_types, false);
......
...@@ -218,6 +218,9 @@ void initGlobalFuncs(GlobalState& g) { ...@@ -218,6 +218,9 @@ void initGlobalFuncs(GlobalState& g) {
g.llvm_value_type_ptr, g.llvm_value_type_ptr); 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.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.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.callattr = getFunc((void*)callattr, "callattr");
g.funcs.callattr0 g.funcs.callattr0
...@@ -228,6 +231,9 @@ void initGlobalFuncs(GlobalState& g) { ...@@ -228,6 +231,9 @@ void initGlobalFuncs(GlobalState& g) {
g.i1, g.i32, g.llvm_value_type_ptr, g.llvm_value_type_ptr); 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.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.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.reoptCompiledFunc = addFunc((void*)reoptCompiledFunc, g.i8_ptr, g.i8_ptr);
g.funcs.compilePartialFunc = addFunc((void*)compilePartialFunc, g.i8_ptr, g.i8_ptr); g.funcs.compilePartialFunc = addFunc((void*)compilePartialFunc, g.i8_ptr, g.i8_ptr);
......
...@@ -42,8 +42,8 @@ struct GlobalFuncs { ...@@ -42,8 +42,8 @@ struct GlobalFuncs {
llvm::Value* unpackIntoArray, *raiseAttributeError, *raiseAttributeErrorStr, *raiseNotIterableError, llvm::Value* unpackIntoArray, *raiseAttributeError, *raiseAttributeErrorStr, *raiseNotIterableError,
*assertNameDefined, *assertFail; *assertNameDefined, *assertFail;
llvm::Value* printFloat, *listAppendInternal; llvm::Value* printFloat, *listAppendInternal;
llvm::Value* runtimeCall0, *runtimeCall1, *runtimeCall2, *runtimeCall3, *runtimeCall; llvm::Value* runtimeCall0, *runtimeCall1, *runtimeCall2, *runtimeCall3, *runtimeCall, *runtimeCallN;
llvm::Value* callattr0, *callattr1, *callattr2, *callattr3, *callattr; llvm::Value* callattr0, *callattr1, *callattr2, *callattr3, *callattr, *callattrN;
llvm::Value* reoptCompiledFunc, *compilePartialFunc; llvm::Value* reoptCompiledFunc, *compilePartialFunc;
llvm::Value* __cxa_begin_catch, *__cxa_end_catch; llvm::Value* __cxa_begin_catch, *__cxa_end_catch;
......
...@@ -580,6 +580,33 @@ Box* strJoin(BoxedString* self, Box* rhs) { ...@@ -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) { Box* strSplit(BoxedString* self, BoxedString* sep, BoxedInt* _max_split) {
assert(self->cls == str_cls); assert(self->cls == str_cls);
if (_max_split->cls != int_cls) if (_max_split->cls != int_cls)
...@@ -1029,6 +1056,9 @@ void setupStr() { ...@@ -1029,6 +1056,9 @@ void setupStr() {
str_cls->giveAttr("join", new BoxedFunction(boxRTFunction((void*)strJoin, STR, 2))); 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( str_cls->giveAttr(
"split", new BoxedFunction(boxRTFunction((void*)strSplit, LIST, 3, 2, false, false), { None, boxInt(-1) })); "split", new BoxedFunction(boxRTFunction((void*)strSplit, LIST, 3, 2, false, false), { None, boxInt(-1) }));
str_cls->giveAttr( str_cls->giveAttr(
......
...@@ -60,3 +60,5 @@ for i in xrange(-3, 5): ...@@ -60,3 +60,5 @@ for i in xrange(-3, 5):
for i in ["", "a", "ab", "aa"]: for i in ["", "a", "ab", "aa"]:
for j in ["", "b", "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 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