Skip to content

Commit

Permalink
Merge pull request #2605 from herwinw/complex_polar
Browse files Browse the repository at this point in the history
Support polar form in String to Complex coercion
  • Loading branch information
herwinw committed Feb 14, 2025
2 parents a1c0738 + e1868ce commit b6ba94a
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 10 deletions.
8 changes: 3 additions & 5 deletions spec/shared/kernel/complex.rb
Original file line number Diff line number Diff line change
Expand Up @@ -114,11 +114,9 @@
end

it "understands 'm@a' to mean a complex number in polar form with 'm' as the modulus, 'a' as the argument" do
NATFIXME "understands 'm@a' to mean a complex number in polar form with 'm' as the modulus, 'a' as the argument", exception: SpecFailedException do
@object.send(@method, '79@4').should == Complex.polar(79, 4)
@object.send(@method, '-79@4').should == Complex.polar(-79, 4)
@object.send(@method, '79@-4').should == Complex.polar(79, -4)
end
@object.send(@method, '79@4').should == Complex.polar(79, 4)
@object.send(@method, '-79@4').should == Complex.polar(-79, 4)
@object.send(@method, '79@-4').should == Complex.polar(79, -4)
end

it "ignores leading whitespaces" do
Expand Down
31 changes: 26 additions & 5 deletions src/kernel_module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ Value KernelModule::Complex(Env *env, StringObject *input, bool exception, bool
auto state = State::Start;
auto real_type = Type::Undefined;
auto imag_type = Type::Undefined;
bool polar = false;
const char *real_start = nullptr;
const char *real_end = nullptr;
const char *imag_start = nullptr;
Expand Down Expand Up @@ -263,19 +264,33 @@ Value KernelModule::Complex(Env *env, StringObject *input, bool exception, bool
*curr_type = Type::Scientific;
*curr_end = c;
} else if (*c == '@') {
// TODO: Parse polar form
return NilObject::the();
} else if (*c == '+' || *c == '-') {
if (*curr_start && *curr_start == *curr_end && (**curr_end == '-' || **curr_end == '+'))
if (polar)
return error();
if (state == State::Imag)
if (state != State::Real)
return error();
if (!c[1])
return error();
polar = true;
curr_start = &imag_start;
curr_end = &imag_end;
*curr_start = *curr_end = c;
curr_type = &imag_type;
*curr_type = Type::Integer;
state = State::Imag;
} else if (*c == '+' || *c == '-') {
if (*curr_start && *curr_start == *curr_end && (**curr_end == '-' || **curr_end == '+'))
return error();
if (state == State::Imag) {
if (!polar && (!*curr_start || *curr_start != *curr_end))
return error();
} else {
curr_start = &imag_start;
curr_end = &imag_end;
*curr_start = *curr_end = c;
curr_type = &imag_type;
*curr_type = Type::Integer;
state = State::Imag;
}
} else if (*c == 'i' || *c == 'I' || *c == 'j' || *c == 'J') {
if (*curr_start && *curr_start == *curr_end && (**curr_end == '-' || **curr_end == '+')) {
// Corner case: '-i' or '+i'
Expand Down Expand Up @@ -326,6 +341,8 @@ Value KernelModule::Complex(Env *env, StringObject *input, bool exception, bool
}
}
if (imag_start != nullptr && imag_end != nullptr) {
if (polar)
imag_start++; // skip '@'
auto tmp = new StringObject { imag_start, static_cast<size_t>(imag_end - imag_start + 1) };
switch (imag_type) {
case Type::Integer:
Expand All @@ -342,6 +359,10 @@ Value KernelModule::Complex(Env *env, StringObject *input, bool exception, bool
return error();
}
}
if (polar) {
auto Complex = GlobalEnv::the()->Object()->const_get(env, "Complex"_s);
return Complex.send(env, "polar"_s, { new_real, new_imag });
}
return new ComplexObject { new_real, new_imag };
}
}
Expand Down

0 comments on commit b6ba94a

Please sign in to comment.