From 1dce95e50b44f08c7173acb32cd93095b7a64b28 Mon Sep 17 00:00:00 2001 From: Shin-ichi MORITA Date: Sun, 14 May 2023 22:00:51 +0900 Subject: [PATCH] Refactored a little. --- include/xemmai/ast.h | 6 +- include/xemmai/code.h | 10 ++-- src/ast.cc | 64 ++++++++++----------- src/code.cc | 20 +++---- src/integer.cc | 100 +++++++-------------------------- test/primitives.xm | 127 ++++++++++++++++++++++++++++++++++++++++-- 6 files changed, 191 insertions(+), 136 deletions(-) diff --git a/include/xemmai/ast.h b/include/xemmai/ast.h index f4178ba1..894a811d 100644 --- a/include/xemmai/ast.h +++ b/include/xemmai/ast.h @@ -660,16 +660,16 @@ template t_operand t_literal::f_emit(t_emit& a_emit, bool a_tail, bool a_operand, bool a_clear) { if (a_operand) return v_value; - if (a_clear) return t_operand(); + if (a_clear) return {}; if (a_tail) { a_emit.f_emit_safe_point(this); - a_emit << static_cast(t_emit::f_instruction_of() + e_instruction__RETURN_B - e_instruction__BOOLEAN) << v_value; + a_emit << static_cast(t_emit::f_instruction_of() + e_instruction__RETURN_BOOLEAN - e_instruction__BOOLEAN) << v_value; } else { a_emit << t_emit::f_instruction_of() << a_emit.v_stack << v_value; } a_emit.f_push(); a_emit.f_at(this); - return t_operand(); + return {}; } } diff --git a/include/xemmai/code.h b/include/xemmai/code.h index eb4d30b5..f75da159 100644 --- a/include/xemmai/code.h +++ b/include/xemmai/code.h @@ -44,11 +44,11 @@ enum t_instruction e_instruction__INTEGER, e_instruction__FLOAT, e_instruction__INSTANCE, - e_instruction__RETURN_N, - e_instruction__RETURN_B, - e_instruction__RETURN_I, - e_instruction__RETURN_F, - e_instruction__RETURN_L, + e_instruction__RETURN_NUL, + e_instruction__RETURN_BOOLEAN, + e_instruction__RETURN_INTEGER, + e_instruction__RETURN_FLOAT, + e_instruction__RETURN_INSTANCE, e_instruction__RETURN_V, e_instruction__RETURN_T, e_instruction__CALL, diff --git a/src/ast.cc b/src/ast.cc index e43cba0d..dcf0f64d 100644 --- a/src/ast.cc +++ b/src/ast.cc @@ -188,7 +188,7 @@ t_operand t_lambda::f_emit(t_emit& a_emit, bool a_tail, bool a_operand, bool a_c } (a_emit << a_emit.v_stack << code).f_push(); if (a_clear) a_emit.f_pop(); - return t_operand(); + return {}; } void t_if::f_flow(t_flow& a_flow) @@ -225,7 +225,7 @@ t_operand t_if::f_emit(t_emit& a_emit, bool a_tail, bool a_operand, bool a_clear a_emit.f_join(v_junction); a_emit.f_target(label1); a_emit.f_merge(v_junction); - return t_operand(); + return {}; } void t_while::f_flow(t_flow& a_flow) @@ -269,7 +269,7 @@ t_operand t_while::f_emit(t_emit& a_emit, bool a_tail, bool a_operand, bool a_cl if (!a_clear) a_emit.f_emit_null(); a_emit.f_target(break0); a_emit.f_merge(v_junction_exit); - return t_operand(); + return {}; } void t_for::f_flow(t_flow& a_flow) @@ -326,7 +326,7 @@ t_operand t_for::f_emit(t_emit& a_emit, bool a_tail, bool a_operand, bool a_clea if (!a_clear) a_emit.f_emit_null(); a_emit.f_target(break0); a_emit.f_merge(v_junction_exit); - return t_operand(); + return {}; } void t_break::f_flow(t_flow& a_flow) @@ -347,7 +347,7 @@ t_operand t_break::f_emit(t_emit& a_emit, bool a_tail, bool a_operand, bool a_cl if (!a_clear) a_emit.f_push(); a_emit.f_join(*a_emit.v_targets->v_break_junction); a_emit << e_instruction__JUMP << *a_emit.v_targets->v_break; - return t_operand(); + return {}; } void t_continue::f_flow(t_flow& a_flow) @@ -359,7 +359,7 @@ t_operand t_continue::f_emit(t_emit& a_emit, bool a_tail, bool a_operand, bool a { if (!a_clear) a_emit.f_push(); a_emit << e_instruction__JUMP << *a_emit.v_targets->v_continue; - return t_operand(); + return {}; } void t_return::f_flow(t_flow& a_flow) @@ -385,7 +385,7 @@ t_operand t_return::f_emit(t_emit& a_emit, bool a_tail, bool a_operand, bool a_c } a_emit.v_stack = stack; if (!a_clear) a_emit.f_push(); - return t_operand(); + return {}; } void t_try::f_flow(t_flow& a_flow) @@ -509,7 +509,7 @@ t_operand t_try::f_emit(t_emit& a_emit, bool a_tail, bool a_operand, bool a_clea join(return0, targets0->v_return, targets0->v_return_junction, targets0->v_return_stack); if (step) a_emit.f_target(*step); a_emit.v_targets = targets0; - return t_operand(); + return {}; } void t_throw::f_flow(t_flow& a_flow) @@ -525,7 +525,7 @@ t_operand t_throw::f_emit(t_emit& a_emit, bool a_tail, bool a_operand, bool a_cl a_emit << e_instruction__THROW << a_emit.v_stack; if (!a_clear) a_emit.f_push(); a_emit.f_at(this); - return t_operand(); + return {}; } void t_object_get::f_flow(t_flow& a_flow) @@ -540,7 +540,7 @@ t_operand t_object_get::f_emit(t_emit& a_emit, bool a_tail, bool a_operand, bool a_emit << e_instruction__OBJECT_GET << a_emit.v_stack - 1 << v_key << 0; a_emit.f_at(this); if (a_clear) a_emit.f_pop(); - return t_operand(); + return {}; } void t_object_get::f_method(t_emit& a_emit) @@ -568,7 +568,7 @@ t_operand t_object_get_indirect::f_emit(t_emit& a_emit, bool a_tail, bool a_oper a_emit.f_pop(); a_emit.f_at(this); if (a_clear) a_emit.f_pop(); - return t_operand(); + return {}; } void t_object_put::f_flow(t_flow& a_flow) @@ -586,7 +586,7 @@ t_operand t_object_put::f_emit(t_emit& a_emit, bool a_tail, bool a_operand, bool a_emit.f_pop(); a_emit.f_at(this); if (a_clear) a_emit.f_pop(); - return t_operand(); + return {}; } void t_object_put_indirect::f_flow(t_flow& a_flow) @@ -606,7 +606,7 @@ t_operand t_object_put_indirect::f_emit(t_emit& a_emit, bool a_tail, bool a_oper a_emit.f_pop().f_pop(); a_emit.f_at(this); if (a_clear) a_emit.f_pop(); - return t_operand(); + return {}; } void t_object_has::f_flow(t_flow& a_flow) @@ -621,7 +621,7 @@ t_operand t_object_has::f_emit(t_emit& a_emit, bool a_tail, bool a_operand, bool a_emit << e_instruction__OBJECT_HAS << a_emit.v_stack - 1 << v_key << 0; a_emit.f_at(this); if (a_clear) a_emit.f_pop(); - return t_operand(); + return {}; } void t_object_has_indirect::f_flow(t_flow& a_flow) @@ -639,7 +639,7 @@ t_operand t_object_has_indirect::f_emit(t_emit& a_emit, bool a_tail, bool a_oper a_emit.f_pop(); a_emit.f_at(this); if (a_clear) a_emit.f_pop(); - return t_operand(); + return {}; } void t_symbol_get::f_flow(t_flow& a_flow) @@ -666,7 +666,7 @@ t_operand t_symbol_get::f_emit(t_emit& a_emit, bool a_tail, bool a_operand, bool a_emit.f_push(); a_emit.f_at(this); if (a_clear) a_emit.f_pop(); - return t_operand(); + return {}; } if (v_variable->v_shared) { size_t instruction = e_instruction__SCOPE_GET0 + (v_resolved < 3 ? v_resolved : 3); @@ -691,7 +691,7 @@ t_operand t_symbol_get::f_emit(t_emit& a_emit, bool a_tail, bool a_operand, bool a_emit.f_push(); a_emit.f_at(this); if (a_clear) a_emit.f_pop(); - return t_operand(); + return {}; } void t_scope_put::f_flow(t_flow& a_flow) @@ -736,7 +736,7 @@ t_operand t_scope_put::f_emit(t_emit& a_emit, bool a_tail, bool a_operand, bool a_emit.f_pop(); } a_emit.f_at(this); - return t_operand(); + return {}; } v_value->f_emit(a_emit, false, false); a_emit.f_emit_safe_point(this); @@ -753,12 +753,12 @@ t_operand t_scope_put::f_emit(t_emit& a_emit, bool a_tail, bool a_operand, bool a_emit << v_variable.v_index; a_emit.f_at(this); if (a_clear) a_emit.f_pop(); - return t_operand(); + return {}; } t_operand t_self::f_emit(t_emit& a_emit, bool a_tail, bool a_operand, bool a_clear) { - if (a_clear) return t_operand(); + if (a_clear) return {}; if (a_tail) a_emit.f_emit_safe_point(this); if (v_outer > 0) { a_emit << static_cast(e_instruction__SCOPE_GET0 + (v_outer < 3 ? v_outer : 3)) << a_emit.v_stack; @@ -769,7 +769,7 @@ t_operand t_self::f_emit(t_emit& a_emit, bool a_tail, bool a_operand, bool a_cle } a_emit.f_push(); a_emit.f_at(this); - return t_operand(); + return {}; } void t_class::f_flow(t_flow& a_flow) @@ -784,7 +784,7 @@ t_operand t_class::f_emit(t_emit& a_emit, bool a_tail, bool a_operand, bool a_cl a_emit << e_instruction__CLASS << a_emit.v_stack - 1; a_emit.f_at(this); if (a_clear) a_emit.f_pop(); - return t_operand(); + return {}; } void t_super::f_flow(t_flow& a_flow) @@ -799,21 +799,21 @@ t_operand t_super::f_emit(t_emit& a_emit, bool a_tail, bool a_operand, bool a_cl a_emit << e_instruction__SUPER << a_emit.v_stack - 1; a_emit.f_at(this); if (a_clear) a_emit.f_pop(); - return t_operand(); + return {}; } t_operand t_null::f_emit(t_emit& a_emit, bool a_tail, bool a_operand, bool a_clear) { if (a_operand) return nullptr; - if (a_clear) return t_operand(); + if (a_clear) return {}; if (a_tail) { a_emit.f_emit_safe_point(this); - (a_emit << e_instruction__RETURN_N).f_push(); + (a_emit << e_instruction__RETURN_NUL).f_push(); } else { a_emit.f_emit_null(); } a_emit.f_at(this); - return t_operand(); + return {}; } void t_unary::f_flow(t_flow& a_flow) @@ -875,7 +875,7 @@ t_operand t_unary::f_emit(t_emit& a_emit, bool a_tail, bool a_operand, bool a_cl a_emit.f_push(); a_emit.f_at(this); if (a_clear) a_emit.f_pop(); - return t_operand(); + return {}; } void t_binary::f_flow(t_flow& a_flow) @@ -1090,7 +1090,7 @@ t_operand t_binary::f_emit(t_emit& a_emit, bool a_tail, bool a_operand, bool a_c a_emit.f_push(); a_emit.f_at(this); if (a_clear) a_emit.f_pop(); - return t_operand(); + return {}; } void t_call::f_flow(t_flow& a_flow) @@ -1131,7 +1131,7 @@ t_operand t_call::f_emit(t_emit& a_emit, bool a_tail, bool a_operand, bool a_cle a_emit.f_push(); a_emit.f_at(this); if (a_clear) a_emit.f_pop(); - return t_operand(); + return {}; } void t_get_at::f_flow(t_flow& a_flow) @@ -1152,7 +1152,7 @@ t_operand t_get_at::f_emit(t_emit& a_emit, bool a_tail, bool a_operand, bool a_c a_emit.f_pop().f_pop(); a_emit.f_at(this); if (a_clear) a_emit.f_pop(); - return t_operand(); + return {}; } void t_get_at::f_bind(t_emit& a_emit) @@ -1184,7 +1184,7 @@ t_operand t_set_at::f_emit(t_emit& a_emit, bool a_tail, bool a_operand, bool a_c a_emit.f_pop().f_pop().f_pop(); a_emit.f_at(this); if (a_clear) a_emit.f_pop(); - return t_operand(); + return {}; } } @@ -1209,7 +1209,7 @@ t_object* t_emit::operator()(ast::t_scope& a_scope) << e_instruction__STACK_GET << v_stack << 0 << e_instruction__SCOPE_PUT0 << v_stack << 0; ast::f_emit_block_without_value(*this, a_scope.v_block); - *this << e_instruction__RETURN_N; + *this << e_instruction__RETURN_NUL; f_resolve(); if (v_safe_points) { t_code::t_variable self; diff --git a/src/code.cc b/src/code.cc index d95b55bc..aea41096 100644 --- a/src/code.cc +++ b/src/code.cc @@ -92,11 +92,11 @@ size_t t_code::f_loop(t_context* a_context, const void*** a_labels) &&label__INTEGER, &&label__FLOAT, &&label__INSTANCE, - &&label__RETURN_N, - &&label__RETURN_B, - &&label__RETURN_I, - &&label__RETURN_F, - &&label__RETURN_L, + &&label__RETURN_NUL, + &&label__RETURN_BOOLEAN, + &&label__RETURN_INTEGER, + &&label__RETURN_FLOAT, + &&label__RETURN_INSTANCE, &&label__RETURN_V, &&label__RETURN_T, &&label__CALL, @@ -493,22 +493,22 @@ size_t t_code::f_loop(t_context* a_context) stack[0] = value; } XEMMAI__CODE__BREAK - XEMMAI__CODE__CASE(RETURN_N) + XEMMAI__CODE__CASE(RETURN_NUL) a_context->f_return(nullptr); return -1; - XEMMAI__CODE__CASE(RETURN_B) + XEMMAI__CODE__CASE(RETURN_BOOLEAN) a_context->f_return(reinterpret_cast(*++pc) != 0); return -1; - XEMMAI__CODE__CASE(RETURN_I) + XEMMAI__CODE__CASE(RETURN_INTEGER) a_context->f_return(reinterpret_cast(*++pc)); return -1; - XEMMAI__CODE__CASE(RETURN_F) + XEMMAI__CODE__CASE(RETURN_FLOAT) { XEMMAI__CODE__FLOAT(v0, v1) a_context->f_return(v0); } return -1; - XEMMAI__CODE__CASE(RETURN_L) + XEMMAI__CODE__CASE(RETURN_INSTANCE) a_context->f_return(*static_cast(*++pc)); return -1; XEMMAI__CODE__CASE(RETURN_V) diff --git a/src/integer.cc b/src/integer.cc index 30ea3a41..c4b2f8fe 100644 --- a/src/integer.cc +++ b/src/integer.cc @@ -13,189 +13,129 @@ t_object* t_type_of::f__string(intptr_t a_self) t_pvalue t_type_of::f__multiply(intptr_t a_self, const t_pvalue& a_value) { switch (a_value.f_tag()) { - case e_tag__NULL: - case e_tag__BOOLEAN: - break; case e_tag__INTEGER: return a_self * a_value.v_integer; case e_tag__FLOAT: return a_self * a_value.v_float; - default: - { - t_object* p = a_value; - if (f_is(p)) return a_self * p->f_as(); - } } + t_object* p = a_value; + if (f_is(p)) return a_self * p->f_as(); f_throw(L"not supported."sv); } t_pvalue t_type_of::f__divide(intptr_t a_self, const t_pvalue& a_value) { switch (a_value.f_tag()) { - case e_tag__NULL: - case e_tag__BOOLEAN: - break; case e_tag__INTEGER: return a_self / a_value.v_integer; case e_tag__FLOAT: return a_self / a_value.v_float; - default: - { - t_object* p = a_value; - if (f_is(p)) return a_self / p->f_as(); - } } + t_object* p = a_value; + if (f_is(p)) return a_self / p->f_as(); f_throw(L"not supported."sv); } t_pvalue t_type_of::f__add(intptr_t a_self, const t_pvalue& a_value) { switch (a_value.f_tag()) { - case e_tag__NULL: - case e_tag__BOOLEAN: - break; case e_tag__INTEGER: return a_self + a_value.v_integer; case e_tag__FLOAT: return a_self + a_value.v_float; - default: - { - t_object* p = a_value; - if (f_is(p)) return a_self + p->f_as(); - } } + t_object* p = a_value; + if (f_is(p)) return a_self + p->f_as(); f_throw(L"not supported."sv); } t_pvalue t_type_of::f__subtract(intptr_t a_self, const t_pvalue& a_value) { switch (a_value.f_tag()) { - case e_tag__NULL: - case e_tag__BOOLEAN: - break; case e_tag__INTEGER: return a_self - a_value.v_integer; case e_tag__FLOAT: return a_self - a_value.v_float; - default: - { - t_object* p = a_value; - if (f_is(p)) return a_self - p->f_as(); - } } + t_object* p = a_value; + if (f_is(p)) return a_self - p->f_as(); f_throw(L"not supported."sv); } bool t_type_of::f__less(intptr_t a_self, const t_pvalue& a_value) { switch (a_value.f_tag()) { - case e_tag__NULL: - case e_tag__BOOLEAN: - break; case e_tag__INTEGER: return a_self < a_value.v_integer; case e_tag__FLOAT: return a_self < a_value.v_float; - default: - { - t_object* p = a_value; - if (f_is(p)) return a_self < p->f_as(); - } } + t_object* p = a_value; + if (f_is(p)) return a_self < p->f_as(); f_throw(L"not supported."sv); } bool t_type_of::f__less_equal(intptr_t a_self, const t_pvalue& a_value) { switch (a_value.f_tag()) { - case e_tag__NULL: - case e_tag__BOOLEAN: - break; case e_tag__INTEGER: return a_self <= a_value.v_integer; case e_tag__FLOAT: return a_self <= a_value.v_float; - default: - { - t_object* p = a_value; - if (f_is(p)) return a_self <= p->f_as(); - } } + t_object* p = a_value; + if (f_is(p)) return a_self <= p->f_as(); f_throw(L"not supported."sv); } bool t_type_of::f__greater(intptr_t a_self, const t_pvalue& a_value) { switch (a_value.f_tag()) { - case e_tag__NULL: - case e_tag__BOOLEAN: - break; case e_tag__INTEGER: return a_self > a_value.v_integer; case e_tag__FLOAT: return a_self > a_value.v_float; - default: - { - t_object* p = a_value; - if (f_is(p)) return a_self > p->f_as(); - } } + t_object* p = a_value; + if (f_is(p)) return a_self > p->f_as(); f_throw(L"not supported."sv); } bool t_type_of::f__greater_equal(intptr_t a_self, const t_pvalue& a_value) { switch (a_value.f_tag()) { - case e_tag__NULL: - case e_tag__BOOLEAN: - break; case e_tag__INTEGER: return a_self >= a_value.v_integer; case e_tag__FLOAT: return a_self >= a_value.v_float; - default: - { - t_object* p = a_value; - if (f_is(p)) return a_self >= p->f_as(); - } } + t_object* p = a_value; + if (f_is(p)) return a_self >= p->f_as(); f_throw(L"not supported."sv); } bool t_type_of::f__equals(intptr_t a_self, const t_pvalue& a_value) { switch (a_value.f_tag()) { - case e_tag__NULL: - case e_tag__BOOLEAN: - return false; case e_tag__INTEGER: return a_self == a_value.v_integer; case e_tag__FLOAT: return a_self == a_value.v_float; - default: - { - t_object* p = a_value; - return f_is(p) && a_self == p->f_as(); - } } + t_object* p = a_value; + return f_is(p) && a_self == p->f_as(); } bool t_type_of::f__not_equals(intptr_t a_self, const t_pvalue& a_value) { switch (a_value.f_tag()) { - case e_tag__NULL: - case e_tag__BOOLEAN: - return true; case e_tag__INTEGER: return a_self != a_value.v_integer; case e_tag__FLOAT: return a_self != a_value.v_float; - default: - { - t_object* p = a_value; - return !f_is(p) || a_self != p->f_as(); - } } + t_object* p = a_value; + return !f_is(p) || a_self != p->f_as(); } void t_type_of::f_define() diff --git a/test/primitives.xm b/test/primitives.xm index 48f6d620..39d39ea5 100644 --- a/test/primitives.xm +++ b/test/primitives.xm @@ -2,14 +2,130 @@ system = Module("system" print = system.out.write_line assert = @(x) x || throw Throwable("Assertion failed." -print("!true = " + (!true) -assert(!true == false +print("!false = " + !false +assert(!false === true +print("!true = " + !true +assert(!true === false +print("false & false = " + (false & false) +assert((false & false) === false +print("true & false = " + (true & false) +assert((true & false) === false +print("false & true = " + (false & true) +assert((false & true) === false print("true & true = " + (true & true) -assert(true & true == true +assert((true & true) === true +print("false | false = " + (false | false) +assert((false | false) === false +print("true | false = " + (true | false) +assert((true | false) === true +print("false | true = " + (false | true) +assert((false | true) === true print("true | true = " + (true | true) -assert(true | true == true +assert((true | true) === true +print("false ^ false = " + (false ^ false) +assert((false ^ false) === false +print("true ^ false = " + (true ^ false) +assert((true ^ false) === true +print("false ^ true = " + (false ^ true) +assert((false ^ true) === true print("true ^ true = " + (true ^ true) -assert(true ^ true == false +assert((true ^ true) === false + +FALSE = false +TRUE = true + +print("!FALSE = " + !FALSE +assert(!FALSE === true +print("!TRUE = " + !TRUE +assert(!TRUE === false +print("FALSE & false = " + (FALSE & false) +assert((FALSE & false) === false +print("TRUE & false = " + (TRUE & false) +assert((TRUE & false) === false +print("FALSE & true = " + (FALSE & true) +assert((FALSE & true) === FALSE +print("TRUE & true = " + (TRUE & true) +assert((TRUE & true) === true +print("FALSE | false = " + (FALSE | false) +assert((FALSE | false) === false +print("TRUE | false = " + (TRUE | false) +assert((TRUE | false) === true +print("FALSE | true = " + (FALSE | true) +assert((FALSE | true) === true +print("TRUE | true = " + (TRUE | true) +assert((TRUE | true) === true +print("FALSE ^ false = " + (FALSE ^ false) +assert((FALSE ^ false) === false +print("TRUE ^ false = " + (TRUE ^ false) +assert((TRUE ^ false) === true +print("FALSE ^ true = " + (FALSE ^ true) +assert((FALSE ^ true) === true +print("TRUE ^ true = " + (TRUE ^ true) +assert((TRUE ^ true) === false + +print("!false = " + !false +assert(!false === TRUE +print("!true = " + !true +assert(!true === FALSE +print("false & FALSE = " + (false & FALSE) +assert((false & FALSE) === FALSE +print("true & FALSE = " + (true & FALSE) +assert((true & FALSE) === FALSE +print("false & TRUE = " + (false & TRUE) +assert((false & TRUE) === FALSE +print("true & TRUE = " + (true & TRUE) +assert((true & TRUE) === TRUE +print("false | FALSE = " + (false | FALSE) +assert((false | FALSE) === FALSE +print("true | FALSE = " + (true | FALSE) +assert((true | FALSE) === TRUE +print("false | TRUE = " + (false | TRUE) +assert((false | TRUE) === TRUE +print("true | TRUE = " + (true | TRUE) +assert((true | TRUE) === TRUE +print("false ^ FALSE = " + (false ^ FALSE) +assert((false ^ FALSE) === FALSE +print("true ^ FALSE = " + (true ^ FALSE) +assert((true ^ FALSE) === TRUE +print("false ^ TRUE = " + (false ^ TRUE) +assert((false ^ TRUE) === TRUE +print("true ^ TRUE = " + (true ^ TRUE) +assert((true ^ TRUE) === FALSE + +print("!FALSE = " + !FALSE +assert(!FALSE === TRUE +print("!TRUE = " + !TRUE +assert(!TRUE === FALSE +print("FALSE & FALSE = " + (FALSE & FALSE) +assert((FALSE & FALSE) === FALSE +print("TRUE & FALSE = " + (TRUE & FALSE) +assert((TRUE & FALSE) === FALSE +print("FALSE & TRUE = " + (FALSE & TRUE) +assert((FALSE & TRUE) === FALSE +print("TRUE & TRUE = " + (TRUE & TRUE) +assert((TRUE & TRUE) === TRUE +print("FALSE | FALSE = " + (FALSE | FALSE) +assert((FALSE | FALSE) === FALSE +print("TRUE | FALSE = " + (TRUE | FALSE) +assert((TRUE | FALSE) === TRUE +print("FALSE | TRUE = " + (FALSE | TRUE) +assert((FALSE | TRUE) === TRUE +print("TRUE | TRUE = " + (TRUE | TRUE) +assert((TRUE | TRUE) === TRUE +print("FALSE ^ FALSE = " + (FALSE ^ FALSE) +assert((FALSE ^ FALSE) === FALSE +print("TRUE ^ FALSE = " + (TRUE ^ FALSE) +assert((TRUE ^ FALSE) === TRUE +print("FALSE ^ TRUE = " + (FALSE ^ TRUE) +assert((FALSE ^ TRUE) === TRUE +print("TRUE ^ TRUE = " + (TRUE ^ TRUE) +assert((TRUE ^ TRUE) === FALSE + +foo = "foo" +assert((false && foo) === false +assert((true && foo) === foo +assert((false || foo) === foo +assert((true || foo) === true print("+(0 + 1) = " + +(0 + 1) assert(+(0 + 1) == 1 @@ -105,6 +221,5 @@ assert(!Bar(1.0).__equals(2.0) assert("" === "" assert("" + "" === "" -foo = "a" assert(foo + "" === foo assert("" + foo === foo