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 Aug 20, 2023
1 parent b11c626 commit c909f12
Show file tree
Hide file tree
Showing 34 changed files with 225 additions and 303 deletions.
4 changes: 4 additions & 0 deletions doc/Literals.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ This page explains literals.

boolean: 'true' | 'false' ;

`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

integer: digit+ ;
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
16 changes: 15 additions & 1 deletion doc/TermExpressions.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ See [PrimaryExpressions](PrimaryExpressions.md).

unary: ('+' | '-' | '!' | '~')* primary ;

Negate operator (`!`) returns `true` if the operand is `false` (`null`), returns `false` (`null`) otherwise.

## Multiplicative Expressions

multiplicative: unary (('*' | '/' | '%') unary)* ;
Expand All @@ -26,13 +28,21 @@ See [PrimaryExpressions](PrimaryExpressions.md).

relational: shift (('<' | '>' | '<=' | '>=') shift)* ;

Relational, equality, and identity operators return either `true` or `false` (`null`).

## Equality Expressions

equality: relational (('==' | '!=') relational)* ;

## Identity Expressions

identity: equality (('===' | '!==') equality)* ;

## And Expressions

and: equality ('&' equality)* ;
and: identity ('&' identity)* ;

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 @@ -46,10 +56,14 @@ See [PrimaryExpressions](PrimaryExpressions.md).

and_also: or ('&&' or)* ;

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 not `false` (`null`), evaluates the right operand and returns it otherwise.

## Conditional Expressions

conditional: or_else ('?' conditional ':' conditional)? ;
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
51 changes: 16 additions & 35 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 @@ -163,14 +153,15 @@ struct t_lambda : t_node, t_scope
struct t_if : t_node
{
std::unique_ptr<t_node> v_condition;
bool v_preserve;
std::vector<std::unique_ptr<t_node>> v_true;
std::vector<std::unique_ptr<t_node>> v_false;
t_block v_block_true;
t_block v_block_false;
t_block v_junction;
t_block v_block_exit;

t_if(const t_at& a_at, std::unique_ptr<t_node>&& a_condition) : t_node(a_at), v_condition(std::move(a_condition))
t_if(const t_at& a_at, std::unique_ptr<t_node>&& a_condition, bool a_preserve = false) : t_node(a_at), v_condition(std::move(a_condition)), v_preserve(a_preserve)
{
}
virtual void f_flow(t_flow& a_flow);
Expand Down Expand Up @@ -417,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 @@ -568,11 +564,6 @@ struct 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 @@ -584,14 +575,9 @@ struct 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)
t_emit& operator<<(t_object* a_operand)
{
v_code->v_instructions.push_back(const_cast<t_pvalue*>(&a_operand));
return *this;
}
t_emit& operator<<(t_svalue& 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 All @@ -618,9 +604,9 @@ struct t_emit
{
v_code->v_ats.push_back({a_node->v_at, f_last()});
}
void f_emit_null()
t_emit& f_emit_null()
{
(*this << e_instruction__NUL << v_stack).f_push();
return (*this << e_instruction__NUL << v_stack).f_push();
}
void f_emit_safe_point(ast::t_node* a_node)
{
Expand All @@ -636,11 +622,6 @@ struct 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 @@ -662,7 +643,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
11 changes: 5 additions & 6 deletions include/xemmai/boolean.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#ifndef XEMMAI__BOOLEAN_H
#define XEMMAI__BOOLEAN_H

#include "object.h"
#include "string.h"

namespace xemmai
{
Expand All @@ -14,18 +14,17 @@ 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(auto&& a_object)
{
return reinterpret_cast<uintptr_t>(static_cast<t_object*>(a_object)) == e_tag__BOOLEAN;
return true;
}
};

XEMMAI__PORTABLE__EXPORT static t_object* f__string(bool a_self);
static intptr_t f__hash(bool a_self)
static t_object* f__string(bool a_self)
{
return a_self ? 1 : 0;
return t_string::f_instantiate(a_self ? L"true"sv : L"null"sv);
}
static void f_define();

Expand Down
2 changes: 1 addition & 1 deletion include/xemmai/class.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ struct t_type_of<t_type> : t_uninstantiatable<t_bears<t_type>>
f_finalize = f_do_scan;
v_get = static_cast<t_pvalue (t_type::*)(t_object*, t_object*, size_t&)>(&t_type_of::f_do_get);
f_string = f_hash = f_not_supported0;
f_get_at = f_set_at = f_plus = f_minus = f_not = f_complement = f_multiply = f_divide = f_modulus = f_subtract = f_left_shift = f_right_shift = f_less = f_less_equal = f_greater = f_greater_equal = f_equals = f_not_equals = f_and = f_xor = f_or = f_not_supported1;
f_get_at = f_set_at = f_plus = f_minus = f_complement = f_multiply = f_divide = f_modulus = f_subtract = f_left_shift = f_right_shift = f_less = f_less_equal = f_greater = f_greater_equal = f_equals = f_not_equals = f_and = f_xor = f_or = f_not_supported1;
}
static void f_do_scan(t_object* a_this, t_scan a_scan);
XEMMAI__PORTABLE__EXPORT t_pvalue f_do_get(t_object* a_this, t_object* a_key, size_t& a_index);
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
20 changes: 2 additions & 18 deletions include/xemmai/fiber.h
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ 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:\
case e_tag__TRUE:\
f_throw(L"not supported."sv);\
case e_tag__INTEGER:\
return a_operator(v_integer);\
Expand All @@ -303,22 +303,6 @@ inline t_pvalue t_value<T_tag>::f_##a_name() const\
XEMMAI__VALUE__UNARY_ARITHMETIC(plus, )
XEMMAI__VALUE__UNARY_ARITHMETIC(minus, -)

template<typename T_tag>
inline t_pvalue t_value<T_tag>::f_not() const
{
auto p = static_cast<t_object*>(*this);
switch (reinterpret_cast<uintptr_t>(p)) {
case e_tag__BOOLEAN:
return !v_boolean;
case e_tag__NULL:
case e_tag__INTEGER:
case e_tag__FLOAT:
f_throw(L"not supported."sv);
default:
XEMMAI__VALUE__UNARY(f_not)
}
}

template<typename T_tag>
inline t_pvalue t_value<T_tag>::f_complement() const
{
Expand All @@ -327,7 +311,7 @@ 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__TRUE:
case e_tag__FLOAT:
f_throw(L"not supported."sv);
default:
Expand Down
2 changes: 1 addition & 1 deletion include/xemmai/float.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ 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>(p) >= e_tag__OBJECT && p->f_type()->f_derives<typename t_fundamental<T>::t_type>();
switch (reinterpret_cast<uintptr_t>(p)) {
case e_tag__NULL:
case e_tag__BOOLEAN:
case e_tag__TRUE:
return false;
case e_tag__INTEGER:
case e_tag__FLOAT:
Expand Down
Loading

0 comments on commit c909f12

Please sign in to comment.