From 7ea2c3e1936485ffc7124e7922b51304faceba4a Mon Sep 17 00:00:00 2001 From: Konstantin Nazarov Date: Tue, 27 Aug 2024 20:15:22 +0100 Subject: [PATCH] Implement mixed arithmetic with integers and floats --- src/common.cpp | 62 +++++++++++++++++++++++++++++++++++++++++++++++- src/common.hpp | 24 +++++++++++++++++++ src/compiler.cpp | 1 + 3 files changed, 86 insertions(+), 1 deletion(-) diff --git a/src/common.cpp b/src/common.cpp index 6691eaf..43a6f09 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -463,39 +463,99 @@ Result Dict::find(const Value& key) const { Result Object::add(const Object&) const { return ERROR(NotImplemented); } Result Object::add(const Int64&) const { return ERROR(NotImplemented); } +Result Object::add(const Float&) const { return ERROR(NotImplemented); } Result Object::sub(const Object&) const { return ERROR(NotImplemented); } Result Object::sub_inv(const Int64&) const { return ERROR(NotImplemented); } +Result Object::sub_inv(const Float&) const { + return ERROR(NotImplemented); +} Result Object::mul(const Object&) const { return ERROR(NotImplemented); } Result Object::mul(const Int64&) const { return ERROR(NotImplemented); } +Result Object::mul(const Float&) const { return ERROR(NotImplemented); } Result Object::div(const Object&) const { return ERROR(NotImplemented); } Result Object::div_inv(const Int64&) const { return ERROR(NotImplemented); } +Result Object::div_inv(const Float&) const { + return ERROR(NotImplemented); +} + Result Int64::add(const Object& rhs) const { return rhs.add(*this); } Result Int64::add(const Int64& rhs) const { return Value(TRY(Int64::create(value() + rhs.value()))); } +Result Int64::add(const Float& rhs) const { + return Value(TRY(Float::create(value() + rhs.value()))); +} + Result Int64::mul(const Object& rhs) const { return rhs.mul(*this); } Result Int64::mul(const Int64& rhs) const { return Value(TRY(Int64::create(value() * rhs.value()))); } +Result Int64::mul(const Float& rhs) const { + return Value(TRY(Float::create(value() * rhs.value()))); +} Result Int64::sub(const Object& rhs) const { return rhs.sub_inv(*this); } Result Int64::sub_inv(const Int64& rhs) const { return Value(TRY(Int64::create(rhs.value() - value()))); } +Result Int64::sub_inv(const Float& rhs) const { + return Value(TRY(Int64::create(rhs.value() - float(value())))); +} Result Int64::div(const Object& rhs) const { return rhs.div_inv(*this); } Result 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 Int64::div_inv(const Float& rhs) const { + return Value(TRY(Float::create(rhs.value() / float(value())))); +} + +Result Float::add(const Object& rhs) const { return rhs.add(*this); } +Result Float::add(const Float& rhs) const { + return Value(TRY(Float::create(value() + rhs.value()))); +} + +Result Float::add(const Int64& rhs) const { + return Value(TRY(Float::create(value() + float(rhs.value())))); +} + +Result Float::mul(const Object& rhs) const { return rhs.mul(*this); } +Result Float::mul(const Float& rhs) const { + return Value(TRY(Float::create(value() * rhs.value()))); +} +Result Float::mul(const Int64& rhs) const { + return Value(TRY(Float::create(value() * float(rhs.value())))); +} + +Result Float::sub(const Object& rhs) const { return rhs.sub_inv(*this); } +Result Float::sub_inv(const Float& rhs) const { + return Value(TRY(Float::create(rhs.value() - value()))); +} +Result Float::sub_inv(const Int64& rhs) const { + return Value(TRY(Float::create(float(rhs.value()) - value()))); +} + +Result Float::div(const Object& rhs) const { return rhs.div_inv(*this); } +Result Float::div_inv(const Float& rhs) const { + return Value(TRY(Float::create(rhs.value() / value()))); +} + +Result Float::div_inv(const Int64& rhs) const { + return Value(TRY(Float::create(float(rhs.value()) / value()))); +} Result Int64::cmp(const Float& rhs) const { return (_value->value > rhs._value->value) - (_value->value < rhs._value->value); diff --git a/src/common.hpp b/src/common.hpp index c1ccaae..1360d28 100644 --- a/src/common.hpp +++ b/src/common.hpp @@ -95,15 +95,19 @@ class Object { virtual Result add(const Object&) const; virtual Result add(const Int64&) const; + virtual Result add(const Float&) const; virtual Result sub(const Object&) const; virtual Result sub_inv(const Int64&) const; + virtual Result sub_inv(const Float&) const; virtual Result mul(const Object&) const; virtual Result mul(const Int64&) const; + virtual Result mul(const Float&) const; virtual Result div(const Object&) const; virtual Result div_inv(const Int64&) const; + virtual Result div_inv(const Float&) const; virtual Result get(const Value& key) const; @@ -693,15 +697,19 @@ class Int64 : public Object { virtual Result add(const Object& rhs) const final; virtual Result add(const Int64& rhs) const final; + virtual Result add(const Float& rhs) const final; virtual Result mul(const Object& rhs) const final; virtual Result mul(const Int64& rhs) const final; + virtual Result mul(const Float& rhs) const final; virtual Result sub(const Object& rhs) const final; virtual Result sub_inv(const Int64& rhs) const final; + virtual Result sub_inv(const Float& rhs) const final; virtual Result div(const Object& rhs) const final; virtual Result div_inv(const Int64& rhs) const final; + virtual Result 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 cmp(const Int64& rhs) const final; + virtual Result add(const Object& rhs) const final; + virtual Result add(const Int64& rhs) const final; + virtual Result add(const Float& rhs) const final; + + virtual Result mul(const Object& rhs) const final; + virtual Result mul(const Int64& rhs) const final; + virtual Result mul(const Float& rhs) const final; + + virtual Result sub(const Object& rhs) const final; + virtual Result sub_inv(const Int64& rhs) const final; + virtual Result sub_inv(const Float& rhs) const final; + + virtual Result div(const Object& rhs) const final; + virtual Result div_inv(const Int64& rhs) const final; + virtual Result div_inv(const Float& rhs) const final; + virtual void move(Object* obj) final { new (obj) Float(std::move(_value)); } static Result create(PodFloat* obj) { diff --git a/src/compiler.cpp b/src/compiler.cpp index 53973f5..0e3d42b 100644 --- a/src/compiler.cpp +++ b/src/compiler.cpp @@ -213,6 +213,7 @@ Result 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: