Skip to content

Commit

Permalink
Unified null and false.
Browse files Browse the repository at this point in the history
  • Loading branch information
shin1m committed Feb 24, 2024
1 parent c99c80d commit 14f979f
Show file tree
Hide file tree
Showing 24 changed files with 75 additions and 155 deletions.
4 changes: 3 additions & 1 deletion doc/Literals.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ This page explains literals.

boolean: 'true' | 'false' ;

`null` and `false` are falsy. The other values are all truthy.
`false` is an alias for `null`.
The only falsy value is `null`. The other values are all truthy.
`true` is the value that is just truthy.

## Integer Literals

Expand Down
2 changes: 1 addition & 1 deletion doc/StackUsage.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@
NUL
|
|N
BOOLEAN
TRUE
|
|B
INTEGER
Expand Down
10 changes: 5 additions & 5 deletions doc/TermExpressions.md
Original file line number Diff line number Diff line change
Expand Up @@ -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` if the operand is `false` (`null`), returns `false` (`null`) otherwise.

## Multiplicative Expressions

Expand All @@ -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` or `false` (`null`).

## Equality Expressions

Expand All @@ -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 boolean (`true`, `false`, or `null`), throws an exception otherwise.

## Xor Expressions

Expand All @@ -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

Expand Down
2 changes: 1 addition & 1 deletion doc/WalkThrough.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ This document walks through xemmai language.
"This is a string."
null
true
false
false # => null

## Variables

Expand Down
21 changes: 7 additions & 14 deletions include/xemmai/ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<t_object*>(a_value ? e_tag__TRUE : e_tag__FALSE))
{
}
t_operand(intptr_t a_value) : v_tag(e_tag__INTEGER), v_integer(a_value)
{
}
Expand Down Expand Up @@ -411,11 +408,16 @@ struct t_super : t_node
virtual t_operand f_emit(t_emit& a_emit, bool a_tail, bool a_operand, bool a_clear);
};

struct t_null : t_node
struct t_boolean : t_node
{
using t_node::t_node;
bool v_value;

t_boolean(const t_at& a_at, bool a_value = false) : t_node(a_at), v_value(a_value)
{
}
virtual t_operand f_emit(t_emit& a_emit, bool a_tail, bool a_operand, bool a_clear);
};
using t_null = t_boolean;

template<typename T>
struct t_literal : t_node
Expand Down Expand Up @@ -562,10 +564,6 @@ struct XEMMAI__LOCAL t_emit
v_code->v_instructions.push_back(reinterpret_cast<void*>(a_operand));
return *this;
}
t_emit& operator<<(bool a_operand)
{
return *this << (a_operand ? 1 : 0);
}
t_emit& operator<<(double a_operand)
{
union
Expand Down Expand Up @@ -624,11 +622,6 @@ struct XEMMAI__LOCAL t_emit
}
};

template<>
constexpr t_instruction t_emit::f_instruction_of<bool>()
{
return e_instruction__BOOLEAN;
}
template<>
constexpr t_instruction t_emit::f_instruction_of<intptr_t>()
{
Expand Down
4 changes: 2 additions & 2 deletions include/xemmai/boolean.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ struct t_type_of<bool> : t_uninstantiatable<t_bears<bool>>
{
static bool f_as(auto&& a_object)
{
return a_object.f_boolean();
return a_object;
}
static bool f_is(t_object* a_object)
{
Expand All @@ -24,7 +24,7 @@ struct t_type_of<bool> : t_uninstantiatable<t_bears<bool>>

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);
return t_string::f_instantiate(a_self ? L"true"sv : L"null"sv);
}
XEMMAI__LOCAL static void f_define();

Expand Down
4 changes: 2 additions & 2 deletions include/xemmai/code.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,12 @@ enum t_instruction
e_instruction__CLASS,
e_instruction__SUPER,
e_instruction__NUL,
e_instruction__BOOLEAN,
e_instruction__TRU,
e_instruction__INTEGER,
e_instruction__FLOAT,
e_instruction__INSTANCE,
e_instruction__RETURN_NUL,
e_instruction__RETURN_BOOLEAN,
e_instruction__RETURN_TRU,
e_instruction__RETURN_INTEGER,
e_instruction__RETURN_FLOAT,
e_instruction__RETURN_INSTANCE,
Expand Down
2 changes: 0 additions & 2 deletions include/xemmai/fiber.h
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,6 @@ inline t_pvalue t_value<T_tag>::f_##a_name() const\
auto p = static_cast<t_object*>(*this);\
switch (reinterpret_cast<uintptr_t>(p)) {\
case e_tag__NULL:\
case e_tag__FALSE:\
case e_tag__TRUE:\
f_throw(L"not supported."sv);\
case e_tag__INTEGER:\
Expand All @@ -288,7 +287,6 @@ inline t_pvalue t_value<T_tag>::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);
Expand Down
1 change: 0 additions & 1 deletion include/xemmai/float.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ struct t_type_of<double> : t_derivable<t_bears<double>, t_derived_primitive<doub
if (!std::is_same_v<typename t_fundamental<T>::t_type, double>) return reinterpret_cast<uintptr_t>(a_object) >= e_tag__OBJECT && a_object->f_type()->f_derives<typename t_fundamental<T>::t_type>();
switch (reinterpret_cast<uintptr_t>(a_object)) {
case e_tag__NULL:
case e_tag__FALSE:
case e_tag__TRUE:
return false;
case e_tag__INTEGER:
Expand Down
15 changes: 2 additions & 13 deletions include/xemmai/global.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
#include "engine.h"
#include "native.h"
#include "method.h"
#include "null.h"
#include "list.h"
#include "map.h"
#include "bytes.h"
Expand Down Expand Up @@ -39,7 +38,6 @@ class t_global : public t_library
t_slot_of<t_type> v_type_advanced_lambda_shared;
t_slot_of<t_type> v_type_method;
t_slot_of<t_type> v_type_throwable;
t_slot_of<t_type> v_type_null;
t_slot_of<t_type> v_type_boolean;
t_slot_of<t_type> v_type_integer;
t_slot_of<t_type> v_type_float;
Expand Down Expand Up @@ -216,7 +214,6 @@ XEMMAI__LIBRARY__TYPE_AS(t_global, t_advanced_lambda<t_lambda>, advanced_lambda)
XEMMAI__LIBRARY__TYPE_AS(t_global, t_advanced_lambda<t_lambda_shared>, advanced_lambda_shared)
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)
Expand Down Expand Up @@ -244,8 +241,6 @@ XEMMAI__PORTABLE__ALWAYS_INLINE inline t_type* t_value<T_tag>::f_type() const
auto p = static_cast<t_object*>(*this);
switch (reinterpret_cast<uintptr_t>(p)) {
case e_tag__NULL:
return f_global()->f_type<std::nullptr_t>();
case e_tag__FALSE:
case e_tag__TRUE:
return f_global()->f_type<bool>();
case e_tag__INTEGER:
Expand Down Expand Up @@ -282,8 +277,6 @@ inline t_pvalue t_value<T_tag>::f_##a_name() const\
auto p = static_cast<t_object*>(*this);\
switch (reinterpret_cast<uintptr_t>(p)) {\
case e_tag__NULL:\
return t_type_of<std::nullptr_t>::f__##a_name(*this);\
case e_tag__FALSE:\
case e_tag__TRUE:\
return t_type_of<bool>::f__##a_name(*this);\
case e_tag__INTEGER:\
Expand Down Expand Up @@ -317,7 +310,6 @@ inline t_pvalue t_value<T_tag>::f_##a_name(const t_pvalue& a_value) const\
auto p = static_cast<t_object*>(*this);\
switch (reinterpret_cast<uintptr_t>(p)) {\
case e_tag__NULL:\
case e_tag__FALSE:\
case e_tag__TRUE:\
f_throw(L"not supported."sv);\
case e_tag__INTEGER:\
Expand All @@ -339,7 +331,6 @@ inline t_pvalue t_value<T_tag>::f_##a_name(const t_pvalue& a_value) const\
f_check<intptr_t>(a_value, L"argument0");\
return static_cast<uintptr_t>(v_integer) a_operator f_as<intptr_t>(a_value);\
case e_tag__NULL:\
case e_tag__FALSE:\
case e_tag__TRUE:\
case e_tag__FLOAT:\
f_throw(L"not supported."sv);\
Expand All @@ -354,7 +345,6 @@ inline t_pvalue t_value<T_tag>::f_##a_name(const t_pvalue& a_value) const\
auto p = static_cast<t_object*>(*this);\
switch (reinterpret_cast<uintptr_t>(p)) {\
case e_tag__NULL:\
case e_tag__FALSE:\
case e_tag__TRUE:\
return a_operator(p == a_value.v_p);\
case e_tag__INTEGER:\
Expand All @@ -371,13 +361,12 @@ inline t_pvalue t_value<T_tag>::f_##a_name(const t_pvalue& a_value) const\
{\
auto p = static_cast<t_object*>(*this);\
switch (reinterpret_cast<uintptr_t>(p)) {\
case e_tag__FALSE:\
case e_tag__NULL:\
case e_tag__TRUE:\
return static_cast<bool>(f_as<bool>(*this) a_operator f_as<bool>(a_value));\
return static_cast<bool>(static_cast<bool>(p) a_operator f_as<bool>(a_value));\
case e_tag__INTEGER:\
f_check<intptr_t>(a_value, L"argument0");\
return v_integer a_operator f_as<intptr_t>(a_value);\
case e_tag__NULL:\
case e_tag__FLOAT:\
f_throw(L"not supported."sv);\
default:\
Expand Down
1 change: 0 additions & 1 deletion include/xemmai/integer.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ struct t_type_of<intptr_t> : t_derivable<t_bears<intptr_t>, 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;
Expand Down
23 changes: 0 additions & 23 deletions include/xemmai/null.h

This file was deleted.

1 change: 0 additions & 1 deletion include/xemmai/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,6 @@ struct t_type::t_cast<T*>
switch (reinterpret_cast<uintptr_t>(a_object)) {
case e_tag__NULL:
return true;
case e_tag__FALSE:
case e_tag__TRUE:
case e_tag__INTEGER:
case e_tag__FLOAT:
Expand Down
11 changes: 1 addition & 10 deletions include/xemmai/value.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ using t_type = t_type_of<t_object>;
enum t_tag
{
e_tag__NULL,
e_tag__FALSE,
e_tag__TRUE,
e_tag__INTEGER,
e_tag__FLOAT,
Expand Down Expand Up @@ -251,7 +250,7 @@ class t_value : public T_tag

public:
using T_tag::T_tag;
t_value(bool a_value) : T_tag(reinterpret_cast<t_object*>(a_value ? e_tag__TRUE : e_tag__FALSE))
t_value(bool a_value) : T_tag(reinterpret_cast<t_object*>(a_value ? e_tag__TRUE : e_tag__NULL))
{
}
template<typename T, std::enable_if_t<std::is_integral_v<T>, bool> = true>
Expand Down Expand Up @@ -301,10 +300,6 @@ class t_value : public T_tag
{
return reinterpret_cast<uintptr_t>(static_cast<t_object*>(*this));
}
bool f_boolean() const
{
return f_tag() >= e_tag__TRUE;
}
intptr_t f_integer() const;
double f_float() const;
t_type_of<t_object>* f_type() const;
Expand Down Expand Up @@ -340,10 +335,6 @@ class t_value : public T_tag
t_value<t_pointer> f_set_at(const t_value<t_pointer>& a_index, const t_value<t_pointer>& a_value) const;
t_value<t_pointer> f_plus() const;
t_value<t_pointer> f_minus() const;
t_value<t_pointer> f_not() const
{
return f_tag() < e_tag__TRUE;
}
t_value<t_pointer> f_complement() const;
t_value<t_pointer> f_multiply(const t_value<t_pointer>& a_value) const;
t_value<t_pointer> f_divide(const t_value<t_pointer>& a_value) const;
Expand Down
1 change: 0 additions & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ add_executable(xemmai
code.cc
lambda.cc
throwable.cc
null.cc
boolean.cc
integer.cc
float.cc
Expand Down
Loading

0 comments on commit 14f979f

Please sign in to comment.