Skip to content

Commit

Permalink
implement Date interface in dynamic-simple (#128)
Browse files Browse the repository at this point in the history
* implement Date interface in dynamic-simple
  • Loading branch information
brucehuke authored Dec 25, 2023
1 parent 5f7a52a commit b042839
Show file tree
Hide file tree
Showing 5 changed files with 140 additions and 15 deletions.
146 changes: 131 additions & 15 deletions runtime-library/libdyntype/dynamic-simple/dyn-value/class/date.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,45 +6,160 @@
#include "dyn_class.h"
#include <time.h>

/**
* @brief char* to time_t
*
* @param str year-month-day hour:minute:second, like
* "2023-12-23 15:58:12"
* @param t time_t addr
* @return int 0: success
*/
int
strtotime(const char *str, time_t *t)
{

int year, month, day, hour, minute, second;
struct tm tm_;

if (sscanf(str, "%d-%d-%d %d:%d:%d", &year, &month, &day, &hour, &minute,
&second)
!= 6) {
return -1;
}
if (hour < 0 || hour > 23) {
return -1;
}
tm_.tm_hour = hour;

if (minute < 0 || minute > 59) {
return -1;
}
tm_.tm_min = minute;

if (second < 0 || second > 59) {
return -1;
}
tm_.tm_sec = second;

tm_.tm_year = year - 1900;
tm_.tm_mon = month - 1;
tm_.tm_mday = day;
tm_.tm_isdst = 0;
*t = mktime(&tm_);

if (*t == -1)
return -1;

return 0;
}

/* Constructor (new Date()) */
DynValue *date_constructor(int argc, DynValue *argv[])
DynValue *
date_constructor(int argc, DynValue *argv[])
{
DyntypeObject *dyn_obj =
(DyntypeObject *)wasm_runtime_malloc(sizeof(DyntypeObject));
DyntypeDate *dyn_obj =
(DyntypeDate *)wasm_runtime_malloc(sizeof(DyntypeDate));
if (!dyn_obj) {
return NULL;
}

if (!init_dyn_object(dyn_obj, DynClassDate)) {
if (!init_dyn_object((DyntypeObject *)dyn_obj, DynClassDate)) {
wasm_runtime_free(dyn_obj);
return NULL;
}

if (argc == 0) {
dyn_obj->time = time(NULL);
}
else if (argc == 1 && argv[0]->class_id == DynClassString) {
DyntypeString *str = (DyntypeString *)argv[0];
if (strtotime(str->data, &dyn_obj->time) != 0) {
return NULL;
}
}
return (DynValue *)dyn_obj;
}

DynValue *date_get_full_year(DynValue *this_val, int argc, DynValue *argv[])
DynValue *
date_get_full_year(DynValue *this_val, int argc, DynValue *argv[])
{
/* TODO */
return dyn_value_new_undefined();
DyntypeDate *dyn_obj = (DyntypeDate *)this_val;
struct tm *timeval = localtime(&(dyn_obj->time));

return dyn_value_new_number((double)(1900 + timeval->tm_year));
}

DynValue *
date_get_month(DynValue *this_val, int argc, DynValue *argv[])
{
DyntypeDate *dyn_obj = (DyntypeDate *)this_val;
struct tm *timeval = localtime(&(dyn_obj->time));
return dyn_value_new_number((double)(timeval->tm_mon));
}

DynValue *
date_get_date(DynValue *this_val, int argc, DynValue *argv[])
{
DyntypeDate *dyn_obj = (DyntypeDate *)this_val;
struct tm *timeval = localtime(&(dyn_obj->time));
return dyn_value_new_number((double)(timeval->tm_mday));
}

DynValue *
date_get_day(DynValue *this_val, int argc, DynValue *argv[])
{
DyntypeDate *dyn_obj = (DyntypeDate *)this_val;
struct tm *timeval = localtime(&(dyn_obj->time));
return dyn_value_new_number((double)(timeval->tm_wday));
}

DynValue *
date_get_hours(DynValue *this_val, int argc, DynValue *argv[])
{
DyntypeDate *dyn_obj = (DyntypeDate *)this_val;
struct tm *timeval = localtime(&(dyn_obj->time));
return dyn_value_new_number((double)(timeval->tm_hour));
}

DynValue *
date_get_minutes(DynValue *this_val, int argc, DynValue *argv[])
{
DyntypeDate *dyn_obj = (DyntypeDate *)this_val;
struct tm *timeval = localtime(&(dyn_obj->time));
return dyn_value_new_number((double)(timeval->tm_min));
}

DynValue *
date_get_seconds(DynValue *this_val, int argc, DynValue *argv[])
{
DyntypeDate *dyn_obj = (DyntypeDate *)this_val;
struct tm *timeval = localtime(&(dyn_obj->time));
return dyn_value_new_number((double)(timeval->tm_sec));
}

/* Date.prototype.xxx */
ClassMethod date_instance_methods[] = {
{ "getFullYear", date_get_full_year }
ClassMethod date_instance_methods[] = {
{ "getFullYear", date_get_full_year },
{ "getMonth", date_get_month },
{ "getDate", date_get_date },
{ "getDay", date_get_day },
{ "getHours", date_get_hours },
{ "getMinutes", date_get_minutes },
{ "getSeconds", date_get_seconds },
};

DynValue *date_now(DynValue *this_val, int argc, DynValue *argv[])
DynValue *
date_now(DynValue *this_val, int argc, DynValue *argv[])
{
// get unix timestamp
time_t now = time(NULL);
return dyn_value_new_number((double)now);
struct timeval start;
gettimeofday(&start, NULL);
return dyn_value_new_number(
(double)(start.tv_sec * 1000 + start.tv_usec / 1000));
}

/* Date.xxx */
ClassMethod date_class_methods[] = {
{ "now", date_now }
};
ClassMethod date_class_methods[] = { { "now", date_now } };

ClassMeta date_class_meta = {
.constructor = date_constructor,
Expand All @@ -53,6 +168,7 @@ ClassMeta date_class_meta = {
.inst_methods = date_instance_methods,
.class_method_num = sizeof(date_class_methods) / sizeof(ClassMethod),
.class_methods = date_class_methods,
.name = "Date"
};

/* Date, never free this object */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@ find_class_constructor(const char *name)
if (!meta)
continue;

assert(meta->name != NULL);

if (!strcmp(meta->name, name))
return meta->constructor;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ ClassMeta object_class_meta = {
.parent_class_id = DynClassNone,
.class_method_num = sizeof(object_class_methods) / sizeof(ClassMethod),
.class_methods = object_class_methods,
.name = "Object"
};

/* Object, never free this object */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,5 @@ ClassMeta string_class_meta = {
.parent_class_id = DynClassObject,
.inst_method_num = sizeof(string_inst_methods) / sizeof(ClassMethod),
.inst_methods = string_inst_methods,
.name = "String"
};
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ typedef struct DyntypeExtref {
int32_t ref;
} DyntypeExtref;

typedef struct DyntypeDate {
DyntypeObject base;
time_t time;
} DyntypeDate;

DynValue *
dyn_value_new_number(double value);

Expand Down

0 comments on commit b042839

Please sign in to comment.