diff --git a/doc/Literals.md b/doc/Literals.md index 4ba3258..fcb042e 100644 --- a/doc/Literals.md +++ b/doc/Literals.md @@ -16,7 +16,10 @@ This page explains literals. boolean: 'true' | 'false' ; -`null` and `false` are falsy. The other values are all truthy. +xemmai has no boolean type. +The only falsy value is `null`. The other values are all truthy. +`true` is an alias for `1.0`, which is float not integer `1` because bitwise operators have to distinguish integer operations and boolean operations. +`false` is an alias for `null`. ## Integer Literals diff --git a/doc/ObjectTraits.md b/doc/ObjectTraits.md index 9b0d63c..39eeb21 100644 --- a/doc/ObjectTraits.md +++ b/doc/ObjectTraits.md @@ -66,7 +66,6 @@ It can be called only if the object is in the shared state which means no thread Method no *1 Throwable yes *3 Null no *1 - Boolean no *1 Integer yes *4 Float yes *4 String no *1 diff --git a/doc/StackUsage.md b/doc/StackUsage.md index cb5a495..da52ece 100644 --- a/doc/StackUsage.md +++ b/doc/StackUsage.md @@ -104,9 +104,6 @@ NUL | |N - BOOLEAN - | - |B INTEGER | |I diff --git a/doc/TermExpressions.md b/doc/TermExpressions.md index d7d1a58..73805b7 100644 --- a/doc/TermExpressions.md +++ b/doc/TermExpressions.md @@ -10,7 +10,7 @@ See [PrimaryExpressions](PrimaryExpressions.md). unary: ('+' | '-' | '!' | '~')* primary ; -Negate operator (`!`) returns `true` if the operand is falsy, returns `false` otherwise. +Negate operator (`!`) returns `true` (`1.0`) if the operand is `false` (`null`), returns `false` (`null`) otherwise. ## Multiplicative Expressions @@ -28,7 +28,7 @@ Negate operator (`!`) returns `true` if the operand is falsy, returns `false` ot relational: shift (('<' | '>' | '<=' | '>=') shift)* ; -Relational, equality, and identity operators return either `true` or `false`. +Relational, equality, and identity operators return either `true` (`1.0`) or `false` (`null`). ## Equality Expressions @@ -42,7 +42,7 @@ Relational, equality, and identity operators return either `true` or `false`. and: identity ('&' identity)* ; -Bitwise operators (`&`, `^`, and `|`) do bitwise operations if both the operands are integers, do boolean operations if the left operand is boolean, throws an exception otherwise. +Bitwise operators (`&`, `^`, and `|`) do bitwise operations if both the operands are integers, do boolean operations if the left operand is `null` or float, throws an exception otherwise. ## Xor Expressions @@ -56,13 +56,13 @@ Bitwise operators (`&`, `^`, and `|`) do bitwise operations if both the operands and_also: or ('&&' or)* ; -Evaluates the left operand, returns it if it is falsy, evaluates the right operand and returns it otherwise. +Evaluates the left operand, returns it if it is `false` (`null`), evaluates the right operand and returns it otherwise. ## Or Else Expressions or_else: and_also ('||' and_also)* ; -Evaluates the left operand, returns it if it is truthy, evaluates the right operand and returns it otherwise. +Evaluates the left operand, returns it if it is not `false` (`null`), evaluates the right operand and returns it otherwise. ## Conditional Expressions diff --git a/doc/WalkThrough.md b/doc/WalkThrough.md index 6aebfda..f1d0df4 100644 --- a/doc/WalkThrough.md +++ b/doc/WalkThrough.md @@ -12,8 +12,8 @@ This document walks through xemmai language. 1.5 * 2.0 # => 3.0 "This is a string." null - true - false + true # => 1.0 + false # => null ## Variables diff --git a/include/xemmai/ast.h b/include/xemmai/ast.h index 4504e59..cbb23ad 100644 --- a/include/xemmai/ast.h +++ b/include/xemmai/ast.h @@ -81,9 +81,6 @@ struct t_operand size_t v_index; }; - t_operand(bool a_value) : v_tag(e_tag__LITERAL), v_value(reinterpret_cast(a_value ? e_tag__TRUE : e_tag__FALSE)) - { - } t_operand(intptr_t a_value) : v_tag(e_tag__INTEGER), v_integer(a_value) { } @@ -562,10 +559,6 @@ struct XEMMAI__LOCAL t_emit v_code->v_instructions.push_back(reinterpret_cast(a_operand)); return *this; } - t_emit& operator<<(bool a_operand) - { - return *this << (a_operand ? 1 : 0); - } t_emit& operator<<(double a_operand) { union @@ -624,11 +617,6 @@ struct XEMMAI__LOCAL t_emit } }; -template<> -constexpr t_instruction t_emit::f_instruction_of() -{ - return e_instruction__BOOLEAN; -} template<> constexpr t_instruction t_emit::f_instruction_of() { diff --git a/include/xemmai/boolean.h b/include/xemmai/boolean.h deleted file mode 100644 index 4c76724..0000000 --- a/include/xemmai/boolean.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef XEMMAI__BOOLEAN_H -#define XEMMAI__BOOLEAN_H - -#include "string.h" - -namespace xemmai -{ - -template<> -struct t_type_of : t_uninstantiatable> -{ - template - struct t_cast - { - static bool f_as(auto&& a_object) - { - return a_object.f_boolean(); - } - static bool f_is(t_object* a_object) - { - return true; - } - }; - - static t_object* f__string(const t_pvalue& a_self) - { - return t_string::f_instantiate(a_self.f_boolean() ? L"true"sv : L"false"sv); - } - XEMMAI__LOCAL static void f_define(); - - using t_base::t_base; -}; - -} - -#endif diff --git a/include/xemmai/code.h b/include/xemmai/code.h index 1024d13..768b776 100644 --- a/include/xemmai/code.h +++ b/include/xemmai/code.h @@ -40,12 +40,10 @@ enum t_instruction e_instruction__CLASS, e_instruction__SUPER, e_instruction__NUL, - e_instruction__BOOLEAN, e_instruction__INTEGER, e_instruction__FLOAT, e_instruction__INSTANCE, e_instruction__RETURN_NUL, - e_instruction__RETURN_BOOLEAN, e_instruction__RETURN_INTEGER, e_instruction__RETURN_FLOAT, e_instruction__RETURN_INSTANCE, diff --git a/include/xemmai/fiber.h b/include/xemmai/fiber.h index fa49413..5943b90 100644 --- a/include/xemmai/fiber.h +++ b/include/xemmai/fiber.h @@ -265,8 +265,6 @@ inline t_pvalue t_value::f_##a_name() const\ auto p = static_cast(*this);\ switch (reinterpret_cast(p)) {\ case e_tag__NULL:\ - case e_tag__FALSE:\ - case e_tag__TRUE:\ f_throw(L"not supported."sv);\ case e_tag__INTEGER:\ return a_operator(v_integer);\ @@ -288,8 +286,6 @@ inline t_pvalue t_value::f_complement() const case e_tag__INTEGER: return ~v_integer; case e_tag__NULL: - case e_tag__FALSE: - case e_tag__TRUE: case e_tag__FLOAT: f_throw(L"not supported."sv); default: diff --git a/include/xemmai/float.h b/include/xemmai/float.h index 272274e..0fcf772 100644 --- a/include/xemmai/float.h +++ b/include/xemmai/float.h @@ -42,8 +42,6 @@ struct t_type_of : t_derivable, t_derived_primitive::t_type, double>) return reinterpret_cast(a_object) >= e_tag__OBJECT && a_object->f_type()->f_derives::t_type>(); switch (reinterpret_cast(a_object)) { case e_tag__NULL: - case e_tag__FALSE: - case e_tag__TRUE: return false; case e_tag__INTEGER: case e_tag__FLOAT: diff --git a/include/xemmai/global.h b/include/xemmai/global.h index bd60b94..649c894 100644 --- a/include/xemmai/global.h +++ b/include/xemmai/global.h @@ -40,7 +40,6 @@ class t_global : public t_library t_slot_of v_type_method; t_slot_of v_type_throwable; t_slot_of v_type_null; - t_slot_of v_type_boolean; t_slot_of v_type_integer; t_slot_of v_type_float; t_slot_of v_type_string; @@ -217,7 +216,6 @@ XEMMAI__LIBRARY__TYPE_AS(t_global, t_advanced_lambda, advanced_ XEMMAI__LIBRARY__TYPE(t_global, method) XEMMAI__LIBRARY__TYPE(t_global, throwable) XEMMAI__LIBRARY__TYPE_AS(t_global, std::nullptr_t, null) -XEMMAI__LIBRARY__TYPE_AS(t_global, bool, boolean) XEMMAI__LIBRARY__TYPE_AS(t_global, intptr_t, integer) XEMMAI__LIBRARY__TYPE_AS(t_global, double, float) XEMMAI__LIBRARY__TYPE(t_global, string) @@ -245,9 +243,6 @@ XEMMAI__PORTABLE__ALWAYS_INLINE inline t_type* t_value::f_type() const switch (reinterpret_cast(p)) { case e_tag__NULL: return f_global()->f_type(); - case e_tag__FALSE: - case e_tag__TRUE: - return f_global()->f_type(); case e_tag__INTEGER: return f_global()->f_type(); case e_tag__FLOAT: @@ -283,9 +278,6 @@ inline t_pvalue t_value::f_##a_name() const\ switch (reinterpret_cast(p)) {\ case e_tag__NULL:\ return t_type_of::f__##a_name(*this);\ - case e_tag__FALSE:\ - case e_tag__TRUE:\ - return t_type_of::f__##a_name(*this);\ case e_tag__INTEGER:\ return t_type_of::f__##a_name(v_integer);\ case e_tag__FLOAT:\ @@ -317,8 +309,6 @@ inline t_pvalue t_value::f_##a_name(const t_pvalue& a_value) const\ auto p = static_cast(*this);\ switch (reinterpret_cast(p)) {\ case e_tag__NULL:\ - case e_tag__FALSE:\ - case e_tag__TRUE:\ f_throw(L"not supported."sv);\ case e_tag__INTEGER:\ return t_type_of::f__##a_name(v_integer, a_value);\ @@ -339,8 +329,6 @@ inline t_pvalue t_value::f_##a_name(const t_pvalue& a_value) const\ f_check(a_value, L"argument0");\ return static_cast(v_integer) a_operator f_as(a_value);\ case e_tag__NULL:\ - case e_tag__FALSE:\ - case e_tag__TRUE:\ case e_tag__FLOAT:\ f_throw(L"not supported."sv);\ default:\ @@ -354,9 +342,7 @@ inline t_pvalue t_value::f_##a_name(const t_pvalue& a_value) const\ auto p = static_cast(*this);\ switch (reinterpret_cast(p)) {\ case e_tag__NULL:\ - case e_tag__FALSE:\ - case e_tag__TRUE:\ - return a_operator(p == a_value.v_p);\ + return a_operator(a_value.f_tag() == e_tag__NULL);\ case e_tag__INTEGER:\ return t_type_of::f__##a_name(v_integer, a_value);\ case e_tag__FLOAT:\ @@ -365,21 +351,19 @@ inline t_pvalue t_value::f_##a_name(const t_pvalue& a_value) const\ XEMMAI__VALUE__BINARY(f_##a_name)\ }\ } -#define XEMMAI__VALUE__BINARY_BITWISE(a_name, a_operator)\ +#define XEMMAI__VALUE__BINARY_BITWISE(a_name, a_operator, a_null, a_true)\ template\ inline t_pvalue t_value::f_##a_name(const t_pvalue& a_value) const\ {\ auto p = static_cast(*this);\ switch (reinterpret_cast(p)) {\ - case e_tag__FALSE:\ - case e_tag__TRUE:\ - return static_cast(f_as(*this) a_operator f_as(a_value));\ + case e_tag__NULL:\ + return a_null;\ case e_tag__INTEGER:\ f_check(a_value, L"argument0");\ return v_integer a_operator f_as(a_value);\ - case e_tag__NULL:\ case e_tag__FLOAT:\ - f_throw(L"not supported."sv);\ + return a_true;\ default:\ XEMMAI__VALUE__BINARY(f_##a_name)\ }\ @@ -398,9 +382,9 @@ XEMMAI__VALUE__BINARY_ARITHMETIC(greater, >) XEMMAI__VALUE__BINARY_ARITHMETIC(greater_equal, >=) XEMMAI__VALUE__BINARY_EQUALITY(equals, ) XEMMAI__VALUE__BINARY_EQUALITY(not_equals, !) -XEMMAI__VALUE__BINARY_BITWISE(and, &) -XEMMAI__VALUE__BINARY_BITWISE(xor, ^) -XEMMAI__VALUE__BINARY_BITWISE(or, |) +XEMMAI__VALUE__BINARY_BITWISE(and, &, false, a_value) +XEMMAI__VALUE__BINARY_BITWISE(xor, ^, a_value, a_value ? false : *this) +XEMMAI__VALUE__BINARY_BITWISE(or, |, a_value, *this) template inline t_object* t_type::f_new(auto&&... a_xs) diff --git a/include/xemmai/integer.h b/include/xemmai/integer.h index 2b51729..2641a60 100644 --- a/include/xemmai/integer.h +++ b/include/xemmai/integer.h @@ -38,8 +38,6 @@ struct t_type_of : t_derivable, t_derived_primitive< case e_tag__INTEGER: return true; case e_tag__NULL: - case e_tag__FALSE: - case e_tag__TRUE: case e_tag__FLOAT: return false; default: diff --git a/include/xemmai/map.h b/include/xemmai/map.h index 3a4c107..9b68d7a 100644 --- a/include/xemmai/map.h +++ b/include/xemmai/map.h @@ -2,7 +2,6 @@ #define XEMMAI__MAP_H #include "sharable.h" -#include "boolean.h" #include "integer.h" namespace xemmai @@ -87,7 +86,7 @@ class t_map : public t_sharable } static bool f_equals(const t_entry& a_p, size_t a_hash, const t_pvalue& a_key) { - return a_p.v_hash == a_hash && f_as(a_p.v_key.f_equals(a_key)); + return a_p.v_hash == a_hash && a_p.v_key.f_equals(a_key); } XEMMAI__PORTABLE__ALWAYS_INLINE t_entry* f_find(const t_pvalue& a_key) const { diff --git a/include/xemmai/object.h b/include/xemmai/object.h index 65bb52b..599f72a 100644 --- a/include/xemmai/object.h +++ b/include/xemmai/object.h @@ -327,7 +327,7 @@ inline void t_slot_of::f_construct(t_object* a_value) v_slot = a_value; } -template +template struct t_type::t_cast { static T f_as(auto&& a_object) @@ -356,8 +356,6 @@ struct t_type::t_cast switch (reinterpret_cast(a_object)) { case e_tag__NULL: return true; - case e_tag__FALSE: - case e_tag__TRUE: case e_tag__INTEGER: case e_tag__FLOAT: return false; diff --git a/include/xemmai/type.h b/include/xemmai/type.h index d90bb37..cd903af 100644 --- a/include/xemmai/type.h +++ b/include/xemmai/type.h @@ -34,6 +34,12 @@ struct t_fundamental> using t_type = t_object; }; +template<> +struct t_fundamental +{ + using t_type = t_object; +}; + template static constexpr std::array f_append(const std::array& a_xs, std::index_sequence, T a_x) { @@ -92,7 +98,7 @@ struct t_fields template<> struct t_type_of { - template struct t_cast; + template struct t_cast; template struct t_cast&> { @@ -105,6 +111,18 @@ struct t_type_of return true; } }; + template + struct t_cast>, bool>>> + { + static bool f_as(auto&& a_object) + { + return a_object; + } + static bool f_is(auto&&) + { + return true; + } + }; using t_library = t_global; static XEMMAI__TYPE__IDS_MODIFIER std::array V_ids{f_type_id()}; diff --git a/include/xemmai/value.h b/include/xemmai/value.h index e26043c..65d44a5 100644 --- a/include/xemmai/value.h +++ b/include/xemmai/value.h @@ -21,8 +21,6 @@ using t_type = t_type_of; enum t_tag { e_tag__NULL, - e_tag__FALSE, - e_tag__TRUE, e_tag__INTEGER, e_tag__FLOAT, e_tag__OBJECT @@ -251,8 +249,9 @@ class t_value : public T_tag public: using T_tag::T_tag; - t_value(bool a_value) : T_tag(reinterpret_cast(a_value ? e_tag__TRUE : e_tag__FALSE)) + t_value(bool a_value) : T_tag(reinterpret_cast(a_value ? e_tag__FLOAT : e_tag__NULL)) { + if (a_value) v_float = 1.0; } template, bool> = true> t_value(T a_value) : T_tag(reinterpret_cast(e_tag__INTEGER)), v_integer(a_value) @@ -301,10 +300,6 @@ class t_value : public T_tag { return reinterpret_cast(static_cast(*this)); } - bool f_boolean() const - { - return f_tag() >= e_tag__TRUE; - } intptr_t f_integer() const; double f_float() const; t_type_of* f_type() const; @@ -340,10 +335,6 @@ class t_value : public T_tag t_value f_set_at(const t_value& a_index, const t_value& a_value) const; t_value f_plus() const; t_value f_minus() const; - t_value f_not() const - { - return f_tag() < e_tag__TRUE; - } t_value f_complement() const; t_value f_multiply(const t_value& a_value) const; t_value f_divide(const t_value& a_value) const; diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d0c2fea..87a218e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -13,7 +13,6 @@ add_executable(xemmai lambda.cc throwable.cc null.cc - boolean.cc integer.cc float.cc string.cc diff --git a/src/ast.cc b/src/ast.cc index a3f6e95..fba2ce2 100644 --- a/src/ast.cc +++ b/src/ast.cc @@ -717,19 +717,10 @@ t_operand t_scope_put::f_emit(t_emit& a_emit, bool a_tail, bool a_operand, bool a_emit << e_instruction__FLOAT << v_variable.v_index << operand.v_float; break; case t_operand::e_tag__LITERAL: - switch (reinterpret_cast(operand.v_value)) { - case e_tag__NULL: - a_emit << e_instruction__NUL << v_variable.v_index; - break; - case e_tag__FALSE: - a_emit << e_instruction__BOOLEAN << v_variable.v_index << 0; - break; - case e_tag__TRUE: - a_emit << e_instruction__BOOLEAN << v_variable.v_index << 1; - break; - default: + if (operand.v_value) a_emit << e_instruction__INSTANCE << v_variable.v_index << operand.v_value; - } + else + a_emit << e_instruction__NUL << v_variable.v_index; break; case t_operand::e_tag__VARIABLE: a_emit << e_instruction__STACK_PUT << operand.v_index << v_variable.v_index; @@ -836,7 +827,7 @@ t_operand t_unary::f_emit(t_emit& a_emit, bool a_tail, bool a_operand, bool a_cl case e_instruction__MINUS_T: return t_literal(v_at, -operand.v_integer).f_emit(a_emit, a_tail, a_operand, a_clear); case e_instruction__NOT_T: - return t_literal(v_at, false).f_emit(a_emit, a_tail, a_operand, a_clear); + return t_null(v_at).f_emit(a_emit, a_tail, a_operand, a_clear); case e_instruction__COMPLEMENT_T: return t_literal(v_at, ~operand.v_integer).f_emit(a_emit, a_tail, a_operand, a_clear); default: @@ -850,7 +841,7 @@ t_operand t_unary::f_emit(t_emit& a_emit, bool a_tail, bool a_operand, bool a_cl case e_instruction__MINUS_T: return t_literal(v_at, -operand.v_float).f_emit(a_emit, a_tail, a_operand, a_clear); case e_instruction__NOT_T: - return t_literal(v_at, false).f_emit(a_emit, a_tail, a_operand, a_clear); + return t_null(v_at).f_emit(a_emit, a_tail, a_operand, a_clear); default: f_throw(L"not supported."sv); } @@ -896,6 +887,10 @@ t_operand t_binary::f_emit(t_emit& a_emit, bool a_tail, bool a_operand, bool a_c a_emit.f_push(); auto left = v_left->f_emit(a_emit, false, true); auto right = v_right->f_emit(a_emit, false, true); + auto boolean = [&](bool a_value) + { + return a_value ? t_literal(v_at, 1.0).f_emit(a_emit, a_tail, a_operand, a_clear) : t_null(v_at).f_emit(a_emit, a_tail, a_operand, a_clear); + }; if (left.v_tag == t_operand::e_tag__INTEGER) { if (right.v_tag == t_operand::e_tag__INTEGER) { a_emit.f_pop(); @@ -915,19 +910,19 @@ t_operand t_binary::f_emit(t_emit& a_emit, bool a_tail, bool a_operand, bool a_c case e_instruction__RIGHT_SHIFT_TT: return t_literal(v_at, static_cast(left.v_integer) >> right.v_integer).f_emit(a_emit, a_tail, a_operand, a_clear); case e_instruction__LESS_TT: - return t_literal(v_at, left.v_integer < right.v_integer).f_emit(a_emit, a_tail, a_operand, a_clear); + return boolean(left.v_integer < right.v_integer); case e_instruction__LESS_EQUAL_TT: - return t_literal(v_at, left.v_integer <= right.v_integer).f_emit(a_emit, a_tail, a_operand, a_clear); + return boolean(left.v_integer <= right.v_integer); case e_instruction__GREATER_TT: - return t_literal(v_at, left.v_integer > right.v_integer).f_emit(a_emit, a_tail, a_operand, a_clear); + return boolean(left.v_integer > right.v_integer); case e_instruction__GREATER_EQUAL_TT: - return t_literal(v_at, left.v_integer >= right.v_integer).f_emit(a_emit, a_tail, a_operand, a_clear); + return boolean(left.v_integer >= right.v_integer); case e_instruction__EQUALS_TT: case e_instruction__IDENTICAL_TT: - return t_literal(v_at, left.v_integer == right.v_integer).f_emit(a_emit, a_tail, a_operand, a_clear); + return boolean(left.v_integer == right.v_integer); case e_instruction__NOT_EQUALS_TT: case e_instruction__NOT_IDENTICAL_TT: - return t_literal(v_at, left.v_integer != right.v_integer).f_emit(a_emit, a_tail, a_operand, a_clear); + return boolean(left.v_integer != right.v_integer); case e_instruction__AND_TT: return t_literal(v_at, left.v_integer & right.v_integer).f_emit(a_emit, a_tail, a_operand, a_clear); case e_instruction__XOR_TT: @@ -949,21 +944,21 @@ t_operand t_binary::f_emit(t_emit& a_emit, bool a_tail, bool a_operand, bool a_c case e_instruction__SUBTRACT_TT: return t_literal(v_at, left.v_integer - right.v_float).f_emit(a_emit, a_tail, a_operand, a_clear); case e_instruction__LESS_TT: - return t_literal(v_at, left.v_integer < right.v_float).f_emit(a_emit, a_tail, a_operand, a_clear); + return boolean(left.v_integer < right.v_float); case e_instruction__LESS_EQUAL_TT: - return t_literal(v_at, left.v_integer <= right.v_float).f_emit(a_emit, a_tail, a_operand, a_clear); + return boolean(left.v_integer <= right.v_float); case e_instruction__GREATER_TT: - return t_literal(v_at, left.v_integer > right.v_float).f_emit(a_emit, a_tail, a_operand, a_clear); + return boolean(left.v_integer > right.v_float); case e_instruction__GREATER_EQUAL_TT: - return t_literal(v_at, left.v_integer >= right.v_float).f_emit(a_emit, a_tail, a_operand, a_clear); + return boolean(left.v_integer >= right.v_float); case e_instruction__EQUALS_TT: - return t_literal(v_at, left.v_integer == right.v_float).f_emit(a_emit, a_tail, a_operand, a_clear); + return boolean(left.v_integer == right.v_float); case e_instruction__NOT_EQUALS_TT: - return t_literal(v_at, left.v_integer != right.v_float).f_emit(a_emit, a_tail, a_operand, a_clear); + return boolean(left.v_integer != right.v_float); case e_instruction__IDENTICAL_TT: - return t_literal(v_at, false).f_emit(a_emit, a_tail, a_operand, a_clear); + return boolean(false); case e_instruction__NOT_IDENTICAL_TT: - return t_literal(v_at, true).f_emit(a_emit, a_tail, a_operand, a_clear); + return boolean(true); default: f_throw(L"not supported."sv); } @@ -981,21 +976,21 @@ t_operand t_binary::f_emit(t_emit& a_emit, bool a_tail, bool a_operand, bool a_c case e_instruction__SUBTRACT_TT: return t_literal(v_at, left.v_float - right.v_integer).f_emit(a_emit, a_tail, a_operand, a_clear); case e_instruction__LESS_TT: - return t_literal(v_at, left.v_float < right.v_integer).f_emit(a_emit, a_tail, a_operand, a_clear); + return boolean(left.v_float < right.v_integer); case e_instruction__LESS_EQUAL_TT: - return t_literal(v_at, left.v_float <= right.v_integer).f_emit(a_emit, a_tail, a_operand, a_clear); + return boolean(left.v_float <= right.v_integer); case e_instruction__GREATER_TT: - return t_literal(v_at, left.v_float > right.v_integer).f_emit(a_emit, a_tail, a_operand, a_clear); + return boolean(left.v_float > right.v_integer); case e_instruction__GREATER_EQUAL_TT: - return t_literal(v_at, left.v_float >= right.v_integer).f_emit(a_emit, a_tail, a_operand, a_clear); + return boolean(left.v_float >= right.v_integer); case e_instruction__EQUALS_TT: - return t_literal(v_at, left.v_float == right.v_integer).f_emit(a_emit, a_tail, a_operand, a_clear); + return boolean(left.v_float == right.v_integer); case e_instruction__NOT_EQUALS_TT: - return t_literal(v_at, left.v_float != right.v_integer).f_emit(a_emit, a_tail, a_operand, a_clear); + return boolean(left.v_float != right.v_integer); case e_instruction__IDENTICAL_TT: - return t_literal(v_at, false).f_emit(a_emit, a_tail, a_operand, a_clear); + return boolean(false); case e_instruction__NOT_IDENTICAL_TT: - return t_literal(v_at, true).f_emit(a_emit, a_tail, a_operand, a_clear); + return boolean(true); default: f_throw(L"not supported."sv); } @@ -1011,19 +1006,24 @@ t_operand t_binary::f_emit(t_emit& a_emit, bool a_tail, bool a_operand, bool a_c case e_instruction__SUBTRACT_TT: return t_literal(v_at, left.v_float - right.v_float).f_emit(a_emit, a_tail, a_operand, a_clear); case e_instruction__LESS_TT: - return t_literal(v_at, left.v_float < right.v_float).f_emit(a_emit, a_tail, a_operand, a_clear); + return boolean(left.v_float < right.v_float); case e_instruction__LESS_EQUAL_TT: - return t_literal(v_at, left.v_float <= right.v_float).f_emit(a_emit, a_tail, a_operand, a_clear); + return boolean(left.v_float <= right.v_float); case e_instruction__GREATER_TT: - return t_literal(v_at, left.v_float > right.v_float).f_emit(a_emit, a_tail, a_operand, a_clear); + return boolean(left.v_float > right.v_float); case e_instruction__GREATER_EQUAL_TT: - return t_literal(v_at, left.v_float >= right.v_float).f_emit(a_emit, a_tail, a_operand, a_clear); + return boolean(left.v_float >= right.v_float); case e_instruction__EQUALS_TT: case e_instruction__IDENTICAL_TT: - return t_literal(v_at, left.v_float == right.v_float).f_emit(a_emit, a_tail, a_operand, a_clear); + return boolean(left.v_float == right.v_float); case e_instruction__NOT_EQUALS_TT: case e_instruction__NOT_IDENTICAL_TT: - return t_literal(v_at, left.v_float != right.v_float).f_emit(a_emit, a_tail, a_operand, a_clear); + return boolean(left.v_float != right.v_float); + case e_instruction__AND_TT: + case e_instruction__OR_TT: + return boolean(true); + case e_instruction__XOR_TT: + return boolean(false); default: f_throw(L"not supported."sv); } diff --git a/src/boolean.cc b/src/boolean.cc deleted file mode 100644 index 5bee8e1..0000000 --- a/src/boolean.cc +++ /dev/null @@ -1,13 +0,0 @@ -#include - -namespace xemmai -{ - -void t_type_of::f_define() -{ - t_define{f_global()} - (f_global()->f_symbol_string(), t_member()) - .f_derive(); -} - -} diff --git a/src/code.cc b/src/code.cc index 4a739bf..3484863 100644 --- a/src/code.cc +++ b/src/code.cc @@ -88,12 +88,10 @@ size_t t_code::f_loop(t_context* a_context, const void*** a_labels) &&label__CLASS, &&label__SUPER, &&label__NUL, - &&label__BOOLEAN, &&label__INTEGER, &&label__FLOAT, &&label__INSTANCE, &&label__RETURN_NUL, - &&label__RETURN_BOOLEAN, &&label__RETURN_INTEGER, &&label__RETURN_FLOAT, &&label__RETURN_INSTANCE, @@ -218,7 +216,7 @@ size_t t_code::f_loop(t_context* a_context) { auto stack = base + reinterpret_cast(*++pc); ++pc; - if (f_as(stack[0])) + if (stack[0]) ++pc; else pc = static_cast(*pc); @@ -451,14 +449,6 @@ size_t t_code::f_loop(t_context* a_context) stack[0] = nullptr; } XEMMAI__CODE__BREAK - XEMMAI__CODE__CASE(BOOLEAN) - { - auto stack = base + reinterpret_cast(*++pc); - auto value = reinterpret_cast(*++pc) != 0; - ++pc; - stack[0] = value; - } - XEMMAI__CODE__BREAK XEMMAI__CODE__CASE(INTEGER) { auto stack = base + reinterpret_cast(*++pc); @@ -493,9 +483,6 @@ size_t t_code::f_loop(t_context* a_context) XEMMAI__CODE__CASE(RETURN_NUL) a_context->f_return(nullptr); return -1; - XEMMAI__CODE__CASE(RETURN_BOOLEAN) - a_context->f_return(reinterpret_cast(*++pc) != 0); - return -1; XEMMAI__CODE__CASE(RETURN_INTEGER) a_context->f_return(reinterpret_cast(*++pc)); return -1; diff --git a/src/code_operator.h b/src/code_operator.h index ad61376..d054905 100644 --- a/src/code_operator.h +++ b/src/code_operator.h @@ -1,6 +1,3 @@ -#define XEMMAI__CODE__CASE_NA(a_name)\ - XEMMAI__CODE__CASE_NAME(a_name)\ - goto label__THROW_NOT_SUPPORTED; #define XEMMAI__CODE__OBJECT_OR_THROW(a_method)\ if (a0.f_tag() >= e_tag__OBJECT) {\ XEMMAI__CODE__OBJECT_CALL(a_method)\ @@ -26,8 +23,6 @@ XEMMAI__CODE__CASE_BEGIN(a_name)\ switch (a0.f_tag()) {\ case e_tag__NULL:\ - case e_tag__FALSE:\ - case e_tag__TRUE:\ goto label__THROW_NOT_SUPPORTED;\ case e_tag__INTEGER:\ XEMMAI__CODE__PRIMITIVE_CALL(a_operator(a0.v_integer))\ @@ -42,7 +37,7 @@ XEMMAI__CODE__UNARY_ARITHMETIC(PLUS, , f_plus) XEMMAI__CODE__UNARY_ARITHMETIC(MINUS, -, f_minus) XEMMAI__CODE__CASE_BEGIN(NOT) - XEMMAI__CODE__PRIMITIVE_CALL(!f_as(a0)) + XEMMAI__CODE__PRIMITIVE_CALL(!a0) XEMMAI__CODE__CASE_END XEMMAI__CODE__CASE_BEGIN(COMPLEMENT) if (a0.f_tag() == e_tag__INTEGER) { @@ -72,9 +67,6 @@ XEMMAI__CODE__CASE_BEGIN(a_name)\ XEMMAI__CODE__PRIMITIVE_CALL(a_operator(XEMMAI__CODE__BINARY_IDENTITY_VALUE))\ XEMMAI__CODE__CASE_END -#if defined(XEMMAI__CODE__BINARY_XF) || defined(XEMMAI__CODE__BINARY_LI) || defined(XEMMAI__CODE__BINARY_LF) -#define XEMMAI__CODE__BINARY_BITWISE(a_name, a_operator, a_method) XEMMAI__CODE__OTHERS_OBJECT(a_name, a_method) -#endif #define XEMMAI__CODE__BINARY_DERIVED_OR_THROW(a_operator, a_type, a_cast, a_field)\ if (a1.f_tag() >= e_tag__OBJECT) {\ if (a1->f_type()->f_derives()) {\ @@ -94,17 +86,6 @@ #if defined(XEMMAI__CODE__BINARY_LX) || defined(XEMMAI__CODE__BINARY_XL) || defined(XEMMAI__CODE__BINARY_XX) #ifdef XEMMAI__CODE__BINARY_LX #define XEMMAI__CODE__BINARY_EQUALITY_PRIMITIVE(a_operator) -#define XEMMAI__CODE__BINARY_BITWISE(a_name, a_operator, a_method)\ - XEMMAI__CODE__CASE_BEGIN(a_name)\ - switch (a0.f_tag()) {\ - case e_tag__FALSE:\ - case e_tag__TRUE:\ - XEMMAI__CODE__PRIMITIVE_CALL(static_cast(f_as(a0) a_operator f_as(a1)))\ - break;\ - default:\ - XEMMAI__CODE__OBJECT_OR_THROW(a_method)\ - }\ - XEMMAI__CODE__CASE_END #else #ifdef XEMMAI__CODE__BINARY_XL #define XEMMAI__CODE__BINARY_INTEGER(a_operator, a_cast) @@ -145,8 +126,6 @@ XEMMAI__CODE__CASE_BEGIN(a_name)\ switch (a0.f_tag()) {\ case e_tag__NULL:\ - case e_tag__FALSE:\ - case e_tag__TRUE:\ goto label__THROW_NOT_SUPPORTED;\ case e_tag__INTEGER:\ XEMMAI__CODE__BINARY_ARITHMETIC_INTEGER(a_operator)\ @@ -176,29 +155,12 @@ XEMMAI__CODE__BINARY_EQUALITY_FLOAT(a_operator)\ XEMMAI__CODE__BINARY_DERIVED_OR_FALSE(a_operator, double, .v_float)\ break; -#define XEMMAI__CODE__BINARY_BITWISE(a_name, a_operator, a_method)\ - XEMMAI__CODE__CASE_BEGIN(a_name)\ - switch (a0.f_tag()) {\ - case e_tag__FALSE:\ - case e_tag__TRUE:\ - XEMMAI__CODE__PRIMITIVE_CALL(static_cast(f_as(a0) a_operator f_as(a1)))\ - break;\ - case e_tag__INTEGER:\ - XEMMAI__CODE__BINARY_INTEGER(a_operator, )\ - XEMMAI__CODE__BINARY_DERIVED_OR_THROW(a_operator, intptr_t, , .v_integer)\ - break;\ - default:\ - XEMMAI__CODE__OBJECT_OR_THROW(a_method)\ - }\ - XEMMAI__CODE__CASE_END #endif #define XEMMAI__CODE__BINARY_EQUALITY(a_name, a_operator, a_method)\ XEMMAI__CODE__CASE_BEGIN(a_name)\ switch (a0.f_tag()) {\ case e_tag__NULL:\ - case e_tag__FALSE:\ - case e_tag__TRUE:\ - XEMMAI__CODE__PRIMITIVE_CALL(a_operator(a0.v_p == a1.v_p))\ + XEMMAI__CODE__PRIMITIVE_CALL(a_operator(a1.f_tag() == e_tag__NULL))\ break;\ XEMMAI__CODE__BINARY_EQUALITY_PRIMITIVE(a_operator)\ default:\ @@ -233,12 +195,6 @@ XEMMAI__CODE__PRIMITIVE_CALL(a_operator(a0.v_float == a1))\ } else XEMMAI__CODE__OBJECT_OR_FALSE(a_operator, a_method)\ XEMMAI__CODE__CASE_END -#define XEMMAI__CODE__BINARY_BITWISE(a_name, a_operator, a_method)\ - XEMMAI__CODE__CASE_BEGIN(a_name)\ - if (a0.f_tag() == e_tag__INTEGER) {\ - XEMMAI__CODE__PRIMITIVE_CALL(a0.v_integer a_operator a1)\ - } else XEMMAI__CODE__OBJECT_OR_THROW(a_method)\ - XEMMAI__CODE__CASE_END #endif #ifdef XEMMAI__CODE__BINARY_XF #define XEMMAI__CODE__BINARY_ARITHMETIC(a_name, a_operator, a_method)\ @@ -296,14 +252,10 @@ XEMMAI__CODE__BINARY_INTEGER(a_operator, static_cast)\ XEMMAI__CODE__BINARY_DERIVED_OR_THROW(a_operator, intptr_t, static_cast, )\ XEMMAI__CODE__CASE_END -#define XEMMAI__CODE__BINARY_BITWISE(a_name, a_operator, a_method)\ - XEMMAI__CODE__CASE_BEGIN(a_name)\ - XEMMAI__CODE__BINARY_INTEGER(a_operator, )\ - XEMMAI__CODE__BINARY_DERIVED_OR_THROW(a_operator, intptr_t, , )\ - XEMMAI__CODE__CASE_END #else -#define XEMMAI__CODE__BINARY_INTEGRAL(a_name, a_operator, a_method) XEMMAI__CODE__CASE_NA(a_name) -#define XEMMAI__CODE__BINARY_BITWISE(a_name, a_operator, a_method) XEMMAI__CODE__CASE_NA(a_name) +#define XEMMAI__CODE__BINARY_INTEGRAL(a_name, a_operator, a_method)\ + XEMMAI__CODE__CASE_NAME(a_name)\ + goto label__THROW_NOT_SUPPORTED; #endif #if defined(XEMMAI__CODE__BINARY_IX) #define XEMMAI__CODE__BINARY_EQUALITY_PRIMITIVE(a_operator)\ @@ -327,6 +279,69 @@ XEMMAI__CODE__BINARY_EQUALITY_PRIMITIVE(a_operator)\ XEMMAI__CODE__BINARY_DERIVED_OR_FALSE(a_operator, XEMMAI__CODE__BINARY_TYPE, )\ XEMMAI__CODE__CASE_END +#endif +#if defined(XEMMAI__CODE__BINARY_LX) || defined(XEMMAI__CODE__BINARY_XL) || defined(XEMMAI__CODE__BINARY_XX) || defined(XEMMAI__CODE__BINARY_FX) +#define XEMMAI__CODE__BINARY_BITWISE_NO_INTEGER if (a1.f_tag() == e_tag__INTEGER) goto label__THROW_NOT_SUPPORTED; +#else +#define XEMMAI__CODE__BINARY_BITWISE_NO_INTEGER +#endif +#if defined(XEMMAI__CODE__BINARY_XL) || defined(XEMMAI__CODE__BINARY_XX) || defined(XEMMAI__CODE__BINARY_XF) +#if defined(XEMMAI__CODE__BINARY_XF) +#define XEMMAI__CODE__BINARY_BITWISE_INTEGER(a_operator) goto label__THROW_NOT_SUPPORTED; +#else +#define XEMMAI__CODE__BINARY_BITWISE_INTEGER(a_operator)\ + XEMMAI__CODE__BINARY_INTEGER(a_operator, )\ + XEMMAI__CODE__BINARY_DERIVED_OR_THROW(a_operator, intptr_t, , .v_integer)\ + break; +#endif +#define XEMMAI__CODE__BINARY_BITWISE(a_name, a_operator, a_method, a_null, a_true)\ + XEMMAI__CODE__CASE_BEGIN(a_name)\ + switch (a0.f_tag()) {\ + case e_tag__NULL:\ + XEMMAI__CODE__BINARY_BITWISE_NO_INTEGER\ + XEMMAI__CODE__PRIMITIVE_CALL(a_null)\ + break;\ + case e_tag__INTEGER:\ + XEMMAI__CODE__BINARY_BITWISE_INTEGER(a_operator)\ + case e_tag__FLOAT:\ + XEMMAI__CODE__BINARY_BITWISE_NO_INTEGER\ + XEMMAI__CODE__PRIMITIVE_CALL(a_true)\ + break;\ + default:\ + XEMMAI__CODE__OBJECT_CALL(a_method)\ + }\ + XEMMAI__CODE__CASE_END +#elif defined(XEMMAI__CODE__BINARY_LF) || defined(XEMMAI__CODE__BINARY_LX) +#define XEMMAI__CODE__BINARY_BITWISE(a_name, a_operator, a_method, a_null, a_true)\ + XEMMAI__CODE__CASE_BEGIN(a_name)\ + XEMMAI__CODE__BINARY_BITWISE_NO_INTEGER\ + if (a0.f_tag() == e_tag__NULL) {\ + XEMMAI__CODE__PRIMITIVE_CALL(a_null)\ + } else {\ + XEMMAI__CODE__OBJECT_CALL(a_method)\ + }\ + XEMMAI__CODE__CASE_END +#elif defined(XEMMAI__CODE__BINARY_XI) +#define XEMMAI__CODE__BINARY_BITWISE(a_name, a_operator, a_method, a_null, a_true)\ + XEMMAI__CODE__CASE_BEGIN(a_name)\ + if (a0.f_tag() == e_tag__INTEGER) {\ + XEMMAI__CODE__PRIMITIVE_CALL(a0.v_integer a_operator a1)\ + } else XEMMAI__CODE__OBJECT_OR_THROW(a_method)\ + XEMMAI__CODE__CASE_END +#elif defined(XEMMAI__CODE__BINARY_LI) +#define XEMMAI__CODE__BINARY_BITWISE(a_name, a_operator, a_method, a_null, a_true) XEMMAI__CODE__OTHERS_OBJECT(a_name, a_method) +#elif defined(XEMMAI__CODE__BINARY_IL) || defined(XEMMAI__CODE__BINARY_IX) +#define XEMMAI__CODE__BINARY_BITWISE(a_name, a_operator, a_method, a_null, a_true)\ + XEMMAI__CODE__CASE_BEGIN(a_name)\ + XEMMAI__CODE__BINARY_INTEGER(a_operator, )\ + XEMMAI__CODE__BINARY_DERIVED_OR_THROW(a_operator, intptr_t, , )\ + XEMMAI__CODE__CASE_END +#elif defined(XEMMAI__CODE__BINARY_FL) || defined(XEMMAI__CODE__BINARY_FX) +#define XEMMAI__CODE__BINARY_BITWISE(a_name, a_operator, a_method, a_null, a_true)\ + XEMMAI__CODE__CASE_BEGIN(a_name)\ + XEMMAI__CODE__BINARY_BITWISE_NO_INTEGER\ + XEMMAI__CODE__PRIMITIVE_CALL(a_true)\ + XEMMAI__CODE__CASE_END #endif XEMMAI__CODE__BINARY_ARITHMETIC(MULTIPLY, *, f_multiply) XEMMAI__CODE__BINARY_ARITHMETIC(DIVIDE, /, f_divide) @@ -343,9 +358,9 @@ XEMMAI__CODE__BINARY_EQUALITY(NOT_EQUALS, !, f_not_equals) XEMMAI__CODE__BINARY_IDENTITY(IDENTICAL, ) XEMMAI__CODE__BINARY_IDENTITY(NOT_IDENTICAL, !) - XEMMAI__CODE__BINARY_BITWISE(AND, &, f_and) - XEMMAI__CODE__BINARY_BITWISE(XOR, ^, f_xor) - XEMMAI__CODE__BINARY_BITWISE(OR, |, f_or) + XEMMAI__CODE__BINARY_BITWISE(AND, &, f_and, false, a1) + XEMMAI__CODE__BINARY_BITWISE(XOR, ^, f_xor, a1, a1 ? t_pvalue(false) : a0) + XEMMAI__CODE__BINARY_BITWISE(OR, |, f_or, a1, a0) #undef XEMMAI__CODE__BINARY_INTEGER #undef XEMMAI__CODE__BINARY_ARITHMETIC_INTEGER #undef XEMMAI__CODE__BINARY_ARITHMETIC_FLOAT @@ -357,6 +372,8 @@ #undef XEMMAI__CODE__BINARY_EQUALITY_PRIMITIVE #undef XEMMAI__CODE__BINARY_EQUALITY #undef XEMMAI__CODE__BINARY_IDENTITY_VALUE +#undef XEMMAI__CODE__BINARY_BITWISE_NO_INTEGER +#undef XEMMAI__CODE__BINARY_BITWISE_INTEGER #undef XEMMAI__CODE__BINARY_BITWISE #undef XEMMAI__CODE__BINARY_TYPE #endif diff --git a/src/global.cc b/src/global.cc index 919a790..ada1bc7 100644 --- a/src/global.cc +++ b/src/global.cc @@ -24,7 +24,6 @@ void t_global::f_scan(t_scan a_scan) a_scan(v_type_method); a_scan(v_type_throwable); a_scan(v_type_null); - a_scan(v_type_boolean); a_scan(v_type_integer); a_scan(v_type_float); a_scan(v_type_string); @@ -131,8 +130,6 @@ std::vector> t_global::f_define() v_type_throwable->v_builtin = true; t_type_of::f_define(); v_type_null->v_builtin = true; - t_type_of::f_define(); - v_type_boolean->v_builtin = true; t_type_of::f_define(); v_type_integer->v_builtin = true; t_type_of::f_define(); @@ -165,7 +162,6 @@ std::vector> t_global::f_define() (L"Method"sv, static_cast(v_type_method)) (L"Throwable"sv, static_cast(v_type_throwable)) (L"Null"sv, static_cast(v_type_null)) - (L"Boolean"sv, static_cast(v_type_boolean)) (L"Integer"sv, static_cast(v_type_integer)) (L"Float"sv, static_cast(v_type_float)) (L"String"sv, static_cast(v_type_string)) diff --git a/src/list.cc b/src/list.cc index e6c9084..af9010e 100644 --- a/src/list.cc +++ b/src/list.cc @@ -266,7 +266,7 @@ void t_type_of::f_sort(t_list& a_self, const t_pvalue& a_callable) } std::sort(p, p + size, [&](const auto& x, const auto& y) { - return f_as(a_callable(x, y)); + return a_callable(x, y); }); a_self.f_owned_or_shared([&] { diff --git a/src/main.cc b/src/main.cc index 0f2324d..8d7f6b5 100644 --- a/src/main.cc +++ b/src/main.cc @@ -189,12 +189,6 @@ class t_debugger : public xemmai::t_debugger case e_tag__NULL: std::fputs("null", v_out); break; - case e_tag__FALSE: - std::fputs("false", v_out); - break; - case e_tag__TRUE: - std::fputs("true", v_out); - break; case e_tag__INTEGER: std::fprintf(v_out, "%" PRIdPTR, f_as(a_value)); break; diff --git a/src/parser.cc b/src/parser.cc index 5ab67c5..7da5d0b 100644 --- a/src/parser.cc +++ b/src/parser.cc @@ -224,10 +224,10 @@ std::unique_ptr t_parser::f_target(bool a_assignable) return std::make_unique(at); case t_lexer::e_token__TRUE: v_lexer.f_next(); - return std::make_unique>(at, true); + return std::make_unique>(at, 1.0); case t_lexer::e_token__FALSE: v_lexer.f_next(); - return std::make_unique>(at, false); + return std::make_unique(at); case t_lexer::e_token__INTEGER: { auto value = v_lexer.f_integer(); diff --git a/src/tuple.cc b/src/tuple.cc index cadfd74..087588f 100644 --- a/src/tuple.cc +++ b/src/tuple.cc @@ -36,7 +36,7 @@ int t_tuple::f_compare(const t_tuple& a_other) const if (i >= a_other.f_size()) return 1; auto& x = (*this)[i]; auto& y = a_other[i]; - if (!f_as(x.f_equals(y))) return f_as(x.f_less(y)) ? -1 : 1; + if (!x.f_equals(y)) return x.f_less(y) ? -1 : 1; } return i < a_other.f_size() ? -1 : 0; } @@ -47,7 +47,7 @@ bool t_tuple::f_equals(const t_pvalue& a_other) const auto& other = a_other->f_as(); if (this == &other) return true; if (v_size != other.v_size) return false; - for (size_t i = 0; i < v_size; ++i) if (!f_as((*this)[i].f_equals(other[i]))) return false; + for (size_t i = 0; i < v_size; ++i) if (!(*this)[i].f_equals(other[i])) return false; return true; } diff --git a/test/errors.xm b/test/errors.xm index 5921a6c..baea649 100644 --- a/test/errors.xm +++ b/test/errors.xm @@ -18,7 +18,6 @@ test_not_supported(@ null[""] test_not_supported(@ null[""] = "" test_not_supported(@ null + "" test_not_supported(@ 0 + "" -test_not_supported(@ 0.0 & "" test_owned = @(x) test(x, @(x) x == "owned by another thread." foo = [ diff --git a/test/primitives.xm b/test/primitives.xm index 7f9a745..d1e698c 100644 --- a/test/primitives.xm +++ b/test/primitives.xm @@ -2,6 +2,9 @@ system = Module("system" print = system.out.write_line assert = @(x) x || throw Throwable("Assertion failed." +assert(false === null +assert(true === 1.0 + print("!false = " + !false assert(!false === true print("!true = " + !true