Implement mixed arithmetic with integers and floats

This commit is contained in:
Konstantin Nazarov 2024-08-27 20:15:22 +01:00
parent f73de2675d
commit 7ea2c3e193
Signed by: knazarov
GPG key ID: 4CFE0A42FA409C22
3 changed files with 86 additions and 1 deletions

View file

@ -463,39 +463,99 @@ Result<uint64_t> Dict::find(const Value& key) const {
Result<Value> Object::add(const Object&) const { return ERROR(NotImplemented); }
Result<Value> Object::add(const Int64&) const { return ERROR(NotImplemented); }
Result<Value> Object::add(const Float&) const { return ERROR(NotImplemented); }
Result<Value> Object::sub(const Object&) const { return ERROR(NotImplemented); }
Result<Value> Object::sub_inv(const Int64&) const {
return ERROR(NotImplemented);
}
Result<Value> Object::sub_inv(const Float&) const {
return ERROR(NotImplemented);
}
Result<Value> Object::mul(const Object&) const { return ERROR(NotImplemented); }
Result<Value> Object::mul(const Int64&) const { return ERROR(NotImplemented); }
Result<Value> Object::mul(const Float&) const { return ERROR(NotImplemented); }
Result<Value> Object::div(const Object&) const { return ERROR(NotImplemented); }
Result<Value> Object::div_inv(const Int64&) const {
return ERROR(NotImplemented);
}
Result<Value> Object::div_inv(const Float&) const {
return ERROR(NotImplemented);
}
Result<Value> Int64::add(const Object& rhs) const { return rhs.add(*this); }
Result<Value> Int64::add(const Int64& rhs) const {
return Value(TRY(Int64::create(value() + rhs.value())));
}
Result<Value> Int64::add(const Float& rhs) const {
return Value(TRY(Float::create(value() + rhs.value())));
}
Result<Value> Int64::mul(const Object& rhs) const { return rhs.mul(*this); }
Result<Value> Int64::mul(const Int64& rhs) const {
return Value(TRY(Int64::create(value() * rhs.value())));
}
Result<Value> Int64::mul(const Float& rhs) const {
return Value(TRY(Float::create(value() * rhs.value())));
}
Result<Value> Int64::sub(const Object& rhs) const { return rhs.sub_inv(*this); }
Result<Value> Int64::sub_inv(const Int64& rhs) const {
return Value(TRY(Int64::create(rhs.value() - value())));
}
Result<Value> Int64::sub_inv(const Float& rhs) const {
return Value(TRY(Int64::create(rhs.value() - float(value()))));
}
Result<Value> Int64::div(const Object& rhs) const { return rhs.div_inv(*this); }
Result<Value> Int64::div_inv(const Int64& rhs) const {
return Value(TRY(Int64::create(rhs.value() / value())));
if (rhs.value() % value() == 0) {
return Value(TRY(Int64::create(rhs.value() / value())));
}
return Value(TRY(Float::create(float(rhs.value()) / float(value()))));
}
Result<Value> Int64::div_inv(const Float& rhs) const {
return Value(TRY(Float::create(rhs.value() / float(value()))));
}
Result<Value> Float::add(const Object& rhs) const { return rhs.add(*this); }
Result<Value> Float::add(const Float& rhs) const {
return Value(TRY(Float::create(value() + rhs.value())));
}
Result<Value> Float::add(const Int64& rhs) const {
return Value(TRY(Float::create(value() + float(rhs.value()))));
}
Result<Value> Float::mul(const Object& rhs) const { return rhs.mul(*this); }
Result<Value> Float::mul(const Float& rhs) const {
return Value(TRY(Float::create(value() * rhs.value())));
}
Result<Value> Float::mul(const Int64& rhs) const {
return Value(TRY(Float::create(value() * float(rhs.value()))));
}
Result<Value> Float::sub(const Object& rhs) const { return rhs.sub_inv(*this); }
Result<Value> Float::sub_inv(const Float& rhs) const {
return Value(TRY(Float::create(rhs.value() - value())));
}
Result<Value> Float::sub_inv(const Int64& rhs) const {
return Value(TRY(Float::create(float(rhs.value()) - value())));
}
Result<Value> Float::div(const Object& rhs) const { return rhs.div_inv(*this); }
Result<Value> Float::div_inv(const Float& rhs) const {
return Value(TRY(Float::create(rhs.value() / value())));
}
Result<Value> Float::div_inv(const Int64& rhs) const {
return Value(TRY(Float::create(float(rhs.value()) / value())));
}
Result<short> Int64::cmp(const Float& rhs) const {
return (_value->value > rhs._value->value) -
(_value->value < rhs._value->value);

View file

@ -95,15 +95,19 @@ class Object {
virtual Result<Value> add(const Object&) const;
virtual Result<Value> add(const Int64&) const;
virtual Result<Value> add(const Float&) const;
virtual Result<Value> sub(const Object&) const;
virtual Result<Value> sub_inv(const Int64&) const;
virtual Result<Value> sub_inv(const Float&) const;
virtual Result<Value> mul(const Object&) const;
virtual Result<Value> mul(const Int64&) const;
virtual Result<Value> mul(const Float&) const;
virtual Result<Value> div(const Object&) const;
virtual Result<Value> div_inv(const Int64&) const;
virtual Result<Value> div_inv(const Float&) const;
virtual Result<Value> get(const Value& key) const;
@ -693,15 +697,19 @@ class Int64 : public Object {
virtual Result<Value> add(const Object& rhs) const final;
virtual Result<Value> add(const Int64& rhs) const final;
virtual Result<Value> add(const Float& rhs) const final;
virtual Result<Value> mul(const Object& rhs) const final;
virtual Result<Value> mul(const Int64& rhs) const final;
virtual Result<Value> mul(const Float& rhs) const final;
virtual Result<Value> sub(const Object& rhs) const final;
virtual Result<Value> sub_inv(const Int64& rhs) const final;
virtual Result<Value> sub_inv(const Float& rhs) const final;
virtual Result<Value> div(const Object& rhs) const final;
virtual Result<Value> div_inv(const Int64& rhs) const final;
virtual Result<Value> div_inv(const Float& rhs) const final;
virtual void move(Object* obj) final { new (obj) Int64(std::move(_value)); }
@ -744,6 +752,22 @@ class Float : public Object {
}
virtual Result<short> cmp(const Int64& rhs) const final;
virtual Result<Value> add(const Object& rhs) const final;
virtual Result<Value> add(const Int64& rhs) const final;
virtual Result<Value> add(const Float& rhs) const final;
virtual Result<Value> mul(const Object& rhs) const final;
virtual Result<Value> mul(const Int64& rhs) const final;
virtual Result<Value> mul(const Float& rhs) const final;
virtual Result<Value> sub(const Object& rhs) const final;
virtual Result<Value> sub_inv(const Int64& rhs) const final;
virtual Result<Value> sub_inv(const Float& rhs) const final;
virtual Result<Value> div(const Object& rhs) const final;
virtual Result<Value> div_inv(const Int64& rhs) const final;
virtual Result<Value> div_inv(const Float& rhs) const final;
virtual void move(Object* obj) final { new (obj) Float(std::move(_value)); }
static Result<Float> create(PodFloat* obj) {

View file

@ -213,6 +213,7 @@ Result<Expression> Compiler::compile_expr(Context& context, Value& expr) {
case Tag::Nil:
return compile_constant(context, expr);
case Tag::Float:
return compile_constant(context, expr);
case Tag::Syntax:
case Tag::Array:
case Tag::ByteArray: