Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
hasumikin committed Jan 26, 2024
1 parent fd1bafc commit efce942
Showing 1 changed file with 187 additions and 24 deletions.
211 changes: 187 additions & 24 deletions parse.y
Expand Up @@ -2130,6 +2130,168 @@ rb_str_to_parser_encoding_string(rb_parser_t *p, VALUE str)
/* Type check */
return rb_parser_encoding_string_new(p, RSTRING_PTR(str), RSTRING_LEN(str), rb_enc_get(str));
}

/*
* Array-like object for parser
*/

#define rb_parser_ary_element VALUE
typedef struct rb_parser_ary {
VALUE flags;
rb_parser_ary_element *data;
long len; // current size
long capa; // capacity
} rb_parser_ary_t;

#define PARRAY(obj) ((struct rb_parser_ary *)(obj))

static void
rb_parser_ary_extend(rb_parser_t *p, VALUE ary, long len)
{
long i;
if (PARRAY(ary)->capa < len) {
PARRAY(ary)->capa = len;
PARRAY(ary)->data = realloc(PARRAY(ary)->data, sizeof(rb_parser_ary_element) * len);
for (i = PARRAY(ary)->len; i < len; i++) {
PARRAY(ary)->data[i] = Qnil;
}
}
}

static VALUE
rb_parser_ary_new_capa(rb_parser_t *p, long len)
{
VALUE ary = (VALUE)xmalloc(sizeof(struct rb_parser_ary));
long i;
PARRAY(ary)->flags = T_ARRAY;
PARRAY(ary)->len = len;
PARRAY(ary)->capa = len;
PARRAY(ary)->data = xmalloc(sizeof(rb_parser_ary_element) * len);
for (i = 0; i < len; i++) {
PARRAY(ary)->data[i] = Qnil;
}
return ary;
}
#define rb_parser_ary_new2 rb_parser_ary_new_capa

static void
rb_parser_ary_store(rb_parser_t *p, VALUE ary, long key, VALUE val)
{
if (PARRAY(ary)->data[key]) {
//rb_gc_force_recycle(PARRAY(ary)->data[key]);
}
if (PARRAY(ary)->len <= key) {
rb_parser_ary_extend(p, ary, key + 1);
}
PARRAY(ary)->data[key] = val;
}

static VALUE
rb_parser_ary_new_from_args(rb_parser_t *p, long len, ...)
{
va_list ar;
VALUE ary;
long i;
ary = rb_parser_ary_new_capa(p, len);
va_start(ar, len);
if (len > 0) {
for (i = 0; i < len; i++) {
rb_parser_ary_store(p, ary, i, va_arg(ar, VALUE));
}
}
va_end(ar);
return ary;
}

inline static VALUE
rb_parser_ary_new(rb_parser_t *p)
{
return rb_parser_ary_new_capa(p, 0);
}

static VALUE
rb_parser_ary_unshift(rb_parser_t *p, VALUE ary, VALUE val)
{
rb_parser_ary_extend(p, ary, PARRAY(ary)->len + 1);
memmove(PARRAY(ary)->data + 1, PARRAY(ary)->data, sizeof(rb_parser_ary_element) * PARRAY(ary)->len);
PARRAY(ary)->data[0] = val;
PARRAY(ary)->len++;
rb_gc_mark(val);
return ary;
}

static VALUE
rb_parser_ary_push(rb_parser_t *p, VALUE ary, VALUE val)
{
rb_parser_ary_extend(p, ary, PARRAY(ary)->len + 1);
PARRAY(ary)->data[PARRAY(ary)->len++] = val;
rb_gc_mark(val);
return ary;
}

static VALUE
rb_parser_ary_reverse(rb_parser_t *p, VALUE ary)
{
long i;
for (i = 0; i < PARRAY(ary)->len / 2; i++) {
VALUE tmp = PARRAY(ary)->data[i];
PARRAY(ary)->data[i] = PARRAY(ary)->data[PARRAY(ary)->len - i - 1];
PARRAY(ary)->data[PARRAY(ary)->len - i - 1] = tmp;
}
return ary;
}

static VALUE
rb_parser_ary_clear(rb_parser_t *p, VALUE ary)
{
long i;
for (i = 0; i < PARRAY(ary)->len; i++) {
//rb_gc_force_recycle(PARRAY(ary)->data[i]);
}
PARRAY(ary)->len = 0;
return ary;
}

/*
static VALUE
rb_parser_ary_concat(rb_parser_t *p, VALUE ary1, VALUE ary2)
{
long i;
rb_parser_ary_extend(p, ary1, PARRAY(ary1)->len + PARRAY(ary2)->len);
for (i = 0; i < PARRAY(ary2)->len; i++) {
PARRAY(ary1)->data[PARRAY(ary1)->len++] = PARRAY(ary2)->data[i];
}
return ary1;
}
*/

static VALUE
rb_parser_ary_join(rb_parser_t *p, VALUE ary, VALUE sep)
{
long i;
VALUE str = rb_str_new(0, 0);
for (i = 0; i < PARRAY(ary)->len; i++) {
if (i > 0) {
rb_str_concat(str, sep);
}
rb_str_concat(str, PARRAY(ary)->data[i]);
}
return str;
}

static void
rb_parser_ary_modify(rb_parser_t *p, VALUE ary)
{
/* what should i do? */
}

#undef RARRAY_LEN
#define RARRAY_LEN(ary) PARRAY(ary)->len
#undef RARRAY_CONST_PTR
#define RARRAY_CONST_PTR(ary) PARRAY(ary)->data
#undef RARRAY_AREF
#define RARRAY_AREF(ary, i) PARRAY(ary)->data[i]

#endif
%}

Expand Down Expand Up @@ -7082,7 +7244,7 @@ parser_has_token(struct parser_params *p)
static VALUE
code_loc_to_ary(struct parser_params *p, const rb_code_location_t *loc)
{
VALUE ary = rb_ary_new_from_args(4,
VALUE ary = rb_parser_ary_new_from_args(p, 4,
INT2NUM(loc->beg_pos.lineno), INT2NUM(loc->beg_pos.column),
INT2NUM(loc->end_pos.lineno), INT2NUM(loc->end_pos.column));
rb_obj_freeze(ary);
Expand All @@ -7096,14 +7258,14 @@ parser_append_tokens(struct parser_params *p, VALUE str, enum yytokentype t, int
VALUE ary;
int token_id;

ary = rb_ary_new2(4);
ary = rb_parser_ary_new2(p, 4);
token_id = p->token_id;
rb_ary_push(ary, INT2FIX(token_id));
rb_ary_push(ary, ID2SYM(parser_token2id(p, t)));
rb_ary_push(ary, str);
rb_ary_push(ary, code_loc_to_ary(p, p->yylloc));
rb_parser_ary_push(p, ary, INT2FIX(token_id));
rb_parser_ary_push(p, ary, ID2SYM(parser_token2id(p, t)));
rb_parser_ary_push(p, ary, str);
rb_parser_ary_push(p, ary, code_loc_to_ary(p, p->yylloc));
rb_obj_freeze(ary);
rb_ary_push(p->tokens, ary);
rb_parser_ary_push(p, p->tokens, ary);
p->token_id++;

if (p->debug) {
Expand Down Expand Up @@ -7614,7 +7776,7 @@ yycompile0(VALUE arg)
VALUE str = rb_default_rs;
n = p->ruby_sourceline;
do {
rb_ary_push(p->debug_lines, str);
rb_parser_ary_push(p, p->debug_lines, str);
} while (--n);
}

Expand Down Expand Up @@ -7927,7 +8089,7 @@ nextline(struct parser_params *p, int set_encoding)
#ifndef RIPPER
if (p->debug_lines) {
if (set_encoding) rb_enc_associate(v, p->enc);
rb_ary_push(p->debug_lines, v);
rb_parser_ary_push(p, p->debug_lines, v);
}
#endif
p->cr_seen = FALSE;
Expand Down Expand Up @@ -13893,23 +14055,23 @@ const_decl_path(struct parser_params *p, NODE **dest)
}
else {
n = RNODE_CDECL(n)->nd_else;
path = rb_ary_new();
path = rb_parser_ary_new(p);
for (; n && nd_type_p(n, NODE_COLON2); n = RNODE_COLON2(n)->nd_head) {
rb_ary_push(path, rb_id2str(RNODE_COLON2(n)->nd_mid));
rb_parser_ary_push(p, path, rb_id2str(RNODE_COLON2(n)->nd_mid));
}
if (n && nd_type_p(n, NODE_CONST)) {
// Const::Name
rb_ary_push(path, rb_id2str(RNODE_CONST(n)->nd_vid));
rb_parser_ary_push(p, path, rb_id2str(RNODE_CONST(n)->nd_vid));
}
else if (n && nd_type_p(n, NODE_COLON3)) {
// ::Const::Name
rb_ary_push(path, rb_str_new(0, 0));
rb_parser_ary_push(p, path, rb_str_new(0, 0));
}
else {
// expression::Name
rb_ary_push(path, rb_str_new_cstr("..."));
rb_parser_ary_push(p, path, rb_str_new_cstr("..."));
}
path = rb_ary_join(rb_ary_reverse(path), rb_str_new_cstr("::"));
path = rb_parser_ary_join(p, rb_parser_ary_reverse(p, path), rb_str_new_cstr("::"));
path = rb_fstring(path);
}
*dest = n = NEW_LIT(path, loc);
Expand Down Expand Up @@ -14021,14 +14183,14 @@ shareable_literal_constant(struct parser_params *p, enum shareability shareable,
return value;

case NODE_ZLIST:
lit = rb_ary_new();
lit = rb_parser_ary_new(p);
OBJ_FREEZE_RAW(lit);
NODE *n = NEW_LIT(lit, loc);
RB_OBJ_WRITTEN(p->ast, Qnil, RNODE_LIT(n)->nd_lit);
return n;

case NODE_LIST:
lit = rb_ary_new();
lit = rb_parser_ary_new(p);
for (NODE *n = value; n; n = RNODE_LIST(n)->nd_next) {
NODE *elt = RNODE_LIST(n)->nd_head;
if (elt) {
Expand All @@ -14037,17 +14199,17 @@ shareable_literal_constant(struct parser_params *p, enum shareability shareable,
RNODE_LIST(n)->nd_head = elt;
}
else if (RTEST(lit)) {
rb_ary_clear(lit);
rb_parser_ary_clear(p, lit);
lit = Qfalse;
}
}
if (RTEST(lit)) {
VALUE e = shareable_literal_value(p, elt);
if (!UNDEF_P(e)) {
rb_ary_push(lit, e);
rb_parser_ary_push(p, lit, e);
}
else {
rb_ary_clear(lit);
rb_parser_ary_clear(p, lit);
lit = Qnil; /* make shareable at runtime */
}
}
Expand Down Expand Up @@ -14110,7 +14272,8 @@ shareable_literal_constant(struct parser_params *p, enum shareability shareable,
value = make_shareable_node(p, value, false, loc);
}
else {
value = NEW_LIT(rb_ractor_make_shareable(lit), loc);
//value = NEW_LIT(rb_ractor_make_shareable(lit), loc);
value = NEW_LIT(lit, loc);
RB_OBJ_WRITTEN(p->ast, Qnil, RNODE_LIT(value)->nd_lit);
}

Expand Down Expand Up @@ -16022,11 +16185,11 @@ rb_ruby_parser_set_script_lines(rb_parser_t *p, VALUE lines)
lines = Qfalse;
}
else if (lines == Qtrue) {
lines = rb_ary_new();
lines = rb_parser_ary_new(p);
}
else {
Check_Type(lines, T_ARRAY);
rb_ary_modify(lines);
rb_parser_ary_modify(p, lines);
}
p->debug_lines = lines;
}
Expand All @@ -16042,7 +16205,7 @@ rb_ruby_parser_keep_tokens(rb_parser_t *p)
{
p->keep_tokens = 1;
// TODO
p->tokens = rb_ary_new();
p->tokens = rb_parser_ary_new(p);
}

#ifndef UNIVERSAL_PARSER
Expand Down

0 comments on commit efce942

Please sign in to comment.