Skip to content

Commit 9dcc342

Browse files
committed
chore: JS array objects
1 parent 85b20d4 commit 9dcc342

File tree

2 files changed

+188
-5
lines changed

2 files changed

+188
-5
lines changed

include/mrdox/Support/JavaScript.hpp

+78-1
Original file line numberDiff line numberDiff line change
@@ -93,12 +93,51 @@ struct Arg
9393
void (*push)(Arg const&, Scope&);
9494

9595
int number = 0;
96+
unsigned u_number = 0;
9697
char const* data = nullptr;
9798
std::size_t size = 0;
9899
unsigned int index = 0; // of object
99100

100101
Arg() = default;
101102

103+
Arg(int i) noexcept
104+
: push(&push_int)
105+
, number(i)
106+
{
107+
}
108+
109+
Arg(bool b) noexcept
110+
: push(&push_bool)
111+
, number(b)
112+
{
113+
}
114+
115+
Arg(unsigned u) noexcept
116+
: push(&push_uint)
117+
, u_number(u)
118+
{
119+
}
120+
121+
Arg(std::size_t u) noexcept
122+
: push(&push_uint)
123+
, u_number(static_cast<std::size_t>(u))
124+
{
125+
}
126+
127+
Arg(char const* s) noexcept
128+
: push(&push_lstring)
129+
, data(s)
130+
, size(std::string_view(s).size())
131+
{
132+
}
133+
134+
Arg(std::string const& s) noexcept
135+
: push(&push_lstring)
136+
, data(s.data())
137+
, size(s.size())
138+
{
139+
}
140+
102141
Arg(std::string_view s) noexcept
103142
: push(&push_lstring)
104143
, data(s.data())
@@ -108,8 +147,11 @@ struct Arg
108147

109148
MRDOX_DECL Arg(Value const& value) noexcept;
110149

111-
MRDOX_DECL static void push_Value(Arg const&, Scope&);
150+
MRDOX_DECL static void push_bool(Arg const&, Scope&);
151+
MRDOX_DECL static void push_int(Arg const&, Scope&);
152+
MRDOX_DECL static void push_uint(Arg const&, Scope&);
112153
MRDOX_DECL static void push_lstring(Arg const&, Scope&);
154+
MRDOX_DECL static void push_Value(Arg const&, Scope&);
113155
};
114156

115157
//------------------------------------------------
@@ -211,6 +253,8 @@ class Value
211253
return type() == Type::string;
212254
}
213255

256+
MRDOX_DECL bool isArray() const noexcept;
257+
214258
bool isObject() const noexcept
215259
{
216260
return type() == Type::object;
@@ -296,6 +340,34 @@ class String : public Value
296340

297341
//------------------------------------------------
298342

343+
/** An ECMAScript Array.
344+
345+
An Array is an Object which has the internal
346+
class Array prototype.
347+
*/
348+
class Array : public Value
349+
{
350+
friend struct Access;
351+
352+
Array(int idx, Scope&) noexcept;
353+
354+
public:
355+
MRDOX_DECL Array(Value value);
356+
MRDOX_DECL Array& operator=(Value value);
357+
MRDOX_DECL explicit Array(Scope& scope);
358+
359+
MRDOX_DECL
360+
std::size_t
361+
size() const;
362+
363+
MRDOX_DECL
364+
void
365+
push_back(
366+
Arg value) const;
367+
};
368+
369+
//------------------------------------------------
370+
299371
/** An ECMAScript Object.
300372
*/
301373
class Object : public Value
@@ -314,6 +386,11 @@ class Object : public Value
314386
MRDOX_DECL Object& operator=(Value value);
315387
MRDOX_DECL explicit Object(Scope& scope);
316388

389+
MRDOX_DECL
390+
void
391+
insert(
392+
std::string_view name, Arg value) const;
393+
317394
/** Call a member or function.
318395
*/
319396
template<class... Args>

source/Support/JavaScript.cpp

+110-4
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,9 @@ struct Access
5151
return (*this)(scope.ctx_);
5252
}
5353

54-
duk_idx_t operator()(Object const& obj) const noexcept
54+
duk_idx_t operator()(Value const& val) const noexcept
5555
{
56-
return obj.idx_;
56+
return val.idx_;
5757
}
5858

5959
void addref(Scope& scope) const noexcept
@@ -150,10 +150,26 @@ Arg(Value const& value) noexcept
150150

151151
void
152152
Arg::
153-
push_Value(
153+
push_bool(
154154
Arg const& arg, Scope& scope)
155155
{
156-
duk_dup(A(scope), arg.index);
156+
duk_push_boolean(A(scope), arg.number != 0);
157+
}
158+
159+
void
160+
Arg::
161+
push_int(
162+
Arg const& arg, Scope& scope)
163+
{
164+
duk_push_int(A(scope), arg.number);
165+
}
166+
167+
void
168+
Arg::
169+
push_uint(
170+
Arg const& arg, Scope& scope)
171+
{
172+
duk_push_uint(A(scope), arg.u_number);
157173
}
158174

159175
void
@@ -164,6 +180,14 @@ push_lstring(
164180
duk_push_lstring(A(scope), arg.data, arg.size);
165181
}
166182

183+
void
184+
Arg::
185+
push_Value(
186+
Arg const& arg, Scope& scope)
187+
{
188+
duk_dup(A(scope), arg.index);
189+
}
190+
167191
//------------------------------------------------
168192

169193
void
@@ -327,6 +351,15 @@ type() const noexcept
327351
}
328352
}
329353

354+
bool
355+
Value::
356+
isArray() const noexcept
357+
{
358+
return
359+
isObject() &&
360+
duk_is_array(A(*scope_), idx_);
361+
}
362+
330363
Expected<Value>
331364
Value::
332365
callImpl(
@@ -388,6 +421,66 @@ get() const noexcept
388421
return { data, size };
389422
}
390423

424+
//------------------------------------------------
425+
//
426+
// Array
427+
//
428+
//------------------------------------------------
429+
430+
Array::
431+
Array(
432+
int idx,
433+
Scope& scope) noexcept
434+
: Value(idx, scope)
435+
{
436+
}
437+
438+
Array::
439+
Array(
440+
Value value)
441+
{
442+
if(! value.isArray())
443+
throw Error("not an Array");
444+
static_cast<Value&>(*this) = std::move(value);
445+
}
446+
447+
Array&
448+
Array::
449+
operator=(
450+
Value value)
451+
{
452+
if(! value.isArray())
453+
throw Error("not an Array");
454+
static_cast<Value&>(*this) = std::move(value);
455+
return *this;
456+
}
457+
458+
Array::
459+
Array(Scope& scope)
460+
: Value(duk_push_array(A(scope)), scope)
461+
{
462+
}
463+
464+
std::size_t
465+
Array::
466+
size() const
467+
{
468+
return duk_get_length(A(*scope_), idx_);
469+
}
470+
471+
void
472+
Array::
473+
push_back(
474+
Arg value) const
475+
{
476+
auto len = duk_get_length(A(*scope_), idx_);
477+
value.push(value, *scope_);
478+
if(! duk_put_prop_index(A(*scope_), idx_, len))
479+
{
480+
// VFALCO What?
481+
}
482+
}
483+
391484
//------------------------------------------------
392485
//
393486
// Object
@@ -430,6 +523,19 @@ Object(Scope& scope)
430523
{
431524
}
432525

526+
void
527+
Object::
528+
insert(
529+
std::string_view name, Arg value) const
530+
{
531+
value.push(value, *scope_);
532+
if(! duk_put_prop_lstring(A(*scope_),
533+
idx_, name.data(), name.size()))
534+
{
535+
// VFALCO What?
536+
}
537+
}
538+
433539
//------------------------------------------------
434540

435541
Expected<Value>

0 commit comments

Comments
 (0)