Skip to content

Commit

Permalink
Experimentally removed Boolean.
Browse files Browse the repository at this point in the history
Since literals other than integers and floats are now either nulls or objects,
the internal type can be changed from const t_pvalue to t_object*.
  • Loading branch information
shin1m committed Feb 22, 2024
1 parent 54ed1c0 commit f5946c6
Show file tree
Hide file tree
Showing 30 changed files with 200 additions and 301 deletions.
5 changes: 4 additions & 1 deletion doc/Literals.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
1 change: 0 additions & 1 deletion doc/ObjectTraits.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 0 additions & 3 deletions doc/StackUsage.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,6 @@
NUL
|
|N
BOOLEAN
|
|B
INTEGER
|
|I
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` (`1.0`) 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` (`1.0`) 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 both the operands are booleans, 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

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
4 changes: 2 additions & 2 deletions doc/WalkThrough.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
35 changes: 5 additions & 30 deletions include/xemmai/ast.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,32 +72,22 @@ struct t_operand
e_tag__TEMPORARY
};

static inline const t_pvalue v_null{};
static inline const t_pvalue v_true{true};
static inline const t_pvalue v_false{false};

t_tag v_tag;
union
{
intptr_t v_integer;
double v_float;
const t_pvalue* v_value;
t_object* v_value;
size_t v_index;
};

t_operand(nullptr_t) : v_tag(e_tag__LITERAL), v_value(&v_null)
{
}
t_operand(bool a_value) : v_tag(e_tag__LITERAL), v_value(a_value ? &v_true : &v_false)
{
}
t_operand(intptr_t a_value) : v_tag(e_tag__INTEGER), v_integer(a_value)
{
}
t_operand(double a_value) : v_tag(e_tag__FLOAT), v_float(a_value)
{
}
t_operand(t_svalue& a_value) : v_tag(e_tag__LITERAL), v_value(reinterpret_cast<const t_pvalue*>(&a_value))
t_operand(t_object* a_value) : v_tag(e_tag__LITERAL), v_value(a_value)
{
}
t_operand() : v_tag(e_tag__TEMPORARY)
Expand Down Expand Up @@ -569,11 +559,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)
{
v_code->v_instructions.push_back(reinterpret_cast<void*>(a_operand ? 1 : 0));
return *this;
}
t_emit& operator<<(double a_operand)
{
union
Expand All @@ -585,14 +570,9 @@ struct XEMMAI__LOCAL t_emit
for (size_t i = 0; i < sizeof(double) / sizeof(void*); ++i) v_code->v_instructions.push_back(v1[i]);
return *this;
}
t_emit& operator<<(const t_pvalue& a_operand)
{
v_code->v_instructions.push_back(const_cast<t_pvalue*>(&a_operand));
return *this;
}
t_emit& operator<<(t_svalue& a_operand)
t_emit& operator<<(t_object* a_operand)
{
v_code->v_instructions.push_back(&a_operand);
v_code->v_instructions.push_back(a_operand);
return *this;
}
t_emit& operator<<(t_label& a_label)
Expand Down Expand Up @@ -637,11 +617,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 All @@ -663,7 +638,7 @@ t_operand t_literal<T>::f_emit(t_emit& a_emit, bool a_tail, bool a_operand, bool
if (a_clear) return {};
if (a_tail) {
a_emit.f_emit_safe_point(this);
a_emit << static_cast<t_instruction>(t_emit::f_instruction_of<T>() + e_instruction__RETURN_BOOLEAN - e_instruction__BOOLEAN) << v_value;
a_emit << static_cast<t_instruction>(t_emit::f_instruction_of<T>() + e_instruction__RETURN_NUL - e_instruction__NUL) << v_value;
} else {
a_emit << t_emit::f_instruction_of<T>() << a_emit.v_stack << v_value;
}
Expand Down
40 changes: 0 additions & 40 deletions include/xemmai/boolean.h

This file was deleted.

2 changes: 0 additions & 2 deletions include/xemmai/code.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
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__BOOLEAN:\
f_throw(L"not supported."sv);\
case e_tag__INTEGER:\
return a_operator(v_integer);\
Expand All @@ -287,7 +286,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__BOOLEAN:
case e_tag__FLOAT:
f_throw(L"not supported."sv);
default:
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__BOOLEAN:
return false;
case e_tag__INTEGER:
case e_tag__FLOAT:
Expand Down
26 changes: 7 additions & 19 deletions include/xemmai/global.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ class t_global : public t_library
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;
t_slot_of<t_type> v_type_string;
Expand Down Expand Up @@ -217,7 +216,6 @@ XEMMAI__LIBRARY__TYPE_AS(t_global, t_advanced_lambda<t_lambda_shared>, 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)
Expand Down Expand Up @@ -245,8 +243,6 @@ XEMMAI__PORTABLE__ALWAYS_INLINE inline t_type* t_value<T_tag>::f_type() const
switch (reinterpret_cast<uintptr_t>(p)) {
case e_tag__NULL:
return f_global()->f_type<std::nullptr_t>();
case e_tag__BOOLEAN:
return f_global()->f_type<bool>();
case e_tag__INTEGER:
return f_global()->f_type<intptr_t>();
case e_tag__FLOAT:
Expand Down Expand Up @@ -282,8 +278,6 @@ inline t_pvalue t_value<T_tag>::f_##a_name() const\
switch (reinterpret_cast<uintptr_t>(p)) {\
case e_tag__NULL:\
return t_type_of<std::nullptr_t>::f__##a_name(*this);\
case e_tag__BOOLEAN:\
return t_type_of<bool>::f__##a_name(v_boolean);\
case e_tag__INTEGER:\
return t_type_of<intptr_t>::f__##a_name(v_integer);\
case e_tag__FLOAT:\
Expand Down Expand Up @@ -315,7 +309,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__BOOLEAN:\
f_throw(L"not supported."sv);\
case e_tag__INTEGER:\
return t_type_of<intptr_t>::f__##a_name(v_integer, a_value);\
Expand All @@ -336,7 +329,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__BOOLEAN:\
case e_tag__FLOAT:\
f_throw(L"not supported."sv);\
default:\
Expand All @@ -351,8 +343,6 @@ inline t_pvalue t_value<T_tag>::f_##a_name(const t_pvalue& a_value) const\
switch (reinterpret_cast<uintptr_t>(p)) {\
case e_tag__NULL:\
return a_operator(p == a_value.v_p);\
case e_tag__BOOLEAN:\
return a_operator(p == a_value.v_p && v_boolean == a_value.v_boolean);\
case e_tag__INTEGER:\
return t_type_of<intptr_t>::f__##a_name(v_integer, a_value);\
case e_tag__FLOAT:\
Expand All @@ -361,21 +351,19 @@ inline t_pvalue t_value<T_tag>::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<typename T_tag>\
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__BOOLEAN:\
if (a_value.f_tag() != e_tag__BOOLEAN) [[unlikely]] f_throw_type_error<bool>(L"argument0");\
return v_boolean a_operator a_value.v_boolean;\
case e_tag__NULL:\
return a_null;\
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);\
return a_true;\
default:\
XEMMAI__VALUE__BINARY(f_##a_name)\
}\
Expand All @@ -394,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<typename T>
inline t_object* t_type::f_new(auto&&... a_xs)
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__BOOLEAN:
case e_tag__FLOAT:
return false;
default:
Expand Down
3 changes: 1 addition & 2 deletions include/xemmai/map.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
#define XEMMAI__MAP_H

#include "sharable.h"
#include "boolean.h"
#include "integer.h"

namespace xemmai
Expand Down Expand Up @@ -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<bool>(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
{
Expand Down
7 changes: 3 additions & 4 deletions include/xemmai/module.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,20 +42,19 @@ struct t_module
struct t_script : t_module::t_body
{
std::wstring v_path;
std::deque<t_svalue> v_slots;
std::deque<t_slot> v_slots;
std::mutex v_mutex;

t_script(std::wstring_view a_path) : v_path(a_path)
{
}
virtual void f_scan(t_scan a_scan);
t_svalue& f_slot(t_object* a_p)
t_object* f_slot(t_object* a_p)
{
v_mutex.lock();
auto& p = v_slots.emplace_back();
v_mutex.unlock();
p = a_p;
return p;
return p = a_p;
}
};

Expand Down
Loading

0 comments on commit f5946c6

Please sign in to comment.