parent
f1e32914eb
commit
cb419e3912
Notes:
git
2025-01-14 23:42:11 +00:00
@ -138,12 +138,6 @@ pm_iseq_add_setlocal(rb_iseq_t *iseq, LINK_ANCHOR *const seq, int line, int node
|
|||||||
#define PM_COMPILE_NOT_POPPED(node) \
|
#define PM_COMPILE_NOT_POPPED(node) \
|
||||||
pm_compile_node(iseq, (node), ret, false, scope_node)
|
pm_compile_node(iseq, (node), ret, false, scope_node)
|
||||||
|
|
||||||
#define PM_SPECIAL_CONSTANT_FLAG ((pm_constant_id_t)(1 << 31))
|
|
||||||
#define PM_CONSTANT_AND ((pm_constant_id_t)(idAnd | PM_SPECIAL_CONSTANT_FLAG))
|
|
||||||
#define PM_CONSTANT_DOT3 ((pm_constant_id_t)(idDot3 | PM_SPECIAL_CONSTANT_FLAG))
|
|
||||||
#define PM_CONSTANT_MULT ((pm_constant_id_t)(idMULT | PM_SPECIAL_CONSTANT_FLAG))
|
|
||||||
#define PM_CONSTANT_POW ((pm_constant_id_t)(idPow | PM_SPECIAL_CONSTANT_FLAG))
|
|
||||||
|
|
||||||
#define PM_NODE_START_LOCATION(parser, node) \
|
#define PM_NODE_START_LOCATION(parser, node) \
|
||||||
((pm_node_location_t) { .line = pm_newline_list_line(&(parser)->newline_list, ((const pm_node_t *) (node))->location.start, (parser)->start_line), .node_id = ((const pm_node_t *) (node))->node_id })
|
((pm_node_location_t) { .line = pm_newline_list_line(&(parser)->newline_list, ((const pm_node_t *) (node))->location.start, (parser)->start_line), .node_id = ((const pm_node_t *) (node))->node_id })
|
||||||
|
|
||||||
|
@ -83,6 +83,12 @@ typedef struct {
|
|||||||
bool parsed;
|
bool parsed;
|
||||||
} pm_parse_result_t;
|
} pm_parse_result_t;
|
||||||
|
|
||||||
|
#define PM_SPECIAL_CONSTANT_FLAG ((pm_constant_id_t)(1 << 31))
|
||||||
|
#define PM_CONSTANT_AND ((pm_constant_id_t)(idAnd | PM_SPECIAL_CONSTANT_FLAG))
|
||||||
|
#define PM_CONSTANT_DOT3 ((pm_constant_id_t)(idDot3 | PM_SPECIAL_CONSTANT_FLAG))
|
||||||
|
#define PM_CONSTANT_MULT ((pm_constant_id_t)(idMULT | PM_SPECIAL_CONSTANT_FLAG))
|
||||||
|
#define PM_CONSTANT_POW ((pm_constant_id_t)(idPow | PM_SPECIAL_CONSTANT_FLAG))
|
||||||
|
|
||||||
VALUE pm_load_file(pm_parse_result_t *result, VALUE filepath, bool load_error);
|
VALUE pm_load_file(pm_parse_result_t *result, VALUE filepath, bool load_error);
|
||||||
VALUE pm_parse_file(pm_parse_result_t *result, VALUE filepath, VALUE *script_lines);
|
VALUE pm_parse_file(pm_parse_result_t *result, VALUE filepath, VALUE *script_lines);
|
||||||
VALUE pm_load_parse_file(pm_parse_result_t *result, VALUE filepath, VALUE *script_lines);
|
VALUE pm_load_parse_file(pm_parse_result_t *result, VALUE filepath, VALUE *script_lines);
|
||||||
|
@ -139,6 +139,11 @@ class TestSyntax < Test::Unit::TestCase
|
|||||||
inner(&)
|
inner(&)
|
||||||
end
|
end
|
||||||
assert_equal(10, all_kwrest(nil, nil, nil, nil, okw1: nil, okw2: nil){10})
|
assert_equal(10, all_kwrest(nil, nil, nil, nil, okw1: nil, okw2: nil){10})
|
||||||
|
|
||||||
|
def evaled(&)
|
||||||
|
eval("inner(&)")
|
||||||
|
end
|
||||||
|
assert_equal(1, evaled{1})
|
||||||
end;
|
end;
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -156,8 +161,10 @@ class TestSyntax < Test::Unit::TestCase
|
|||||||
def b(*); c(*) end
|
def b(*); c(*) end
|
||||||
def c(*a); a end
|
def c(*a); a end
|
||||||
def d(*); b(*, *) end
|
def d(*); b(*, *) end
|
||||||
|
def e(*); eval("b(*)") end
|
||||||
assert_equal([1, 2], b(1, 2))
|
assert_equal([1, 2], b(1, 2))
|
||||||
assert_equal([1, 2, 1, 2], d(1, 2))
|
assert_equal([1, 2, 1, 2], d(1, 2))
|
||||||
|
assert_equal([1, 2], e(1, 2))
|
||||||
end;
|
end;
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -177,10 +184,12 @@ class TestSyntax < Test::Unit::TestCase
|
|||||||
def d(**); b(k: 1, **) end
|
def d(**); b(k: 1, **) end
|
||||||
def e(**); b(**, k: 1) end
|
def e(**); b(**, k: 1) end
|
||||||
def f(a: nil, **); b(**) end
|
def f(a: nil, **); b(**) end
|
||||||
|
def g(**); eval("b(**)") end
|
||||||
assert_equal({a: 1, k: 3}, b(a: 1, k: 3))
|
assert_equal({a: 1, k: 3}, b(a: 1, k: 3))
|
||||||
assert_equal({a: 1, k: 3}, d(a: 1, k: 3))
|
assert_equal({a: 1, k: 3}, d(a: 1, k: 3))
|
||||||
assert_equal({a: 1, k: 1}, e(a: 1, k: 3))
|
assert_equal({a: 1, k: 1}, e(a: 1, k: 3))
|
||||||
assert_equal({k: 3}, f(a: 1, k: 3))
|
assert_equal({k: 3}, f(a: 1, k: 3))
|
||||||
|
assert_equal({a: 1, k: 3}, g(a: 1, k: 3))
|
||||||
end;
|
end;
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -2010,6 +2019,7 @@ eom
|
|||||||
obj4 = obj1.clone
|
obj4 = obj1.clone
|
||||||
obj5 = obj1.clone
|
obj5 = obj1.clone
|
||||||
obj1.instance_eval('def foo(...) bar(...) end', __FILE__, __LINE__)
|
obj1.instance_eval('def foo(...) bar(...) end', __FILE__, __LINE__)
|
||||||
|
obj1.instance_eval('def foo(...) eval("bar(...)") end', __FILE__, __LINE__)
|
||||||
obj4.instance_eval("def foo ...\n bar(...)\n""end", __FILE__, __LINE__)
|
obj4.instance_eval("def foo ...\n bar(...)\n""end", __FILE__, __LINE__)
|
||||||
obj5.instance_eval("def foo ...; bar(...); end", __FILE__, __LINE__)
|
obj5.instance_eval("def foo ...; bar(...); end", __FILE__, __LINE__)
|
||||||
|
|
||||||
|
72
vm_eval.c
72
vm_eval.c
@ -1692,12 +1692,24 @@ pm_eval_make_iseq(VALUE src, VALUE fname, int line,
|
|||||||
iseq = parent;
|
iseq = parent;
|
||||||
rb_encoding *encoding = rb_enc_get(src);
|
rb_encoding *encoding = rb_enc_get(src);
|
||||||
|
|
||||||
|
#define FORWARDING_POSITIONALS_CHR '*'
|
||||||
|
#define FORWARDING_POSITIONALS_STR "*"
|
||||||
|
#define FORWARDING_KEYWORDS_CHR ':'
|
||||||
|
#define FORWARDING_KEYWORDS_STR ":"
|
||||||
|
#define FORWARDING_BLOCK_CHR '&'
|
||||||
|
#define FORWARDING_BLOCK_STR "&"
|
||||||
|
#define FORWARDING_ALL_CHR '.'
|
||||||
|
#define FORWARDING_ALL_STR "."
|
||||||
|
|
||||||
for (int scopes_index = 0; scopes_index < scopes_count; scopes_index++) {
|
for (int scopes_index = 0; scopes_index < scopes_count; scopes_index++) {
|
||||||
VALUE iseq_value = (VALUE)iseq;
|
VALUE iseq_value = (VALUE)iseq;
|
||||||
int locals_count = ISEQ_BODY(iseq)->local_table_size;
|
int locals_count = ISEQ_BODY(iseq)->local_table_size;
|
||||||
|
|
||||||
pm_options_scope_t *options_scope = &result.options.scopes[scopes_count - scopes_index - 1];
|
pm_options_scope_t *options_scope = &result.options.scopes[scopes_count - scopes_index - 1];
|
||||||
pm_options_scope_init(options_scope, locals_count);
|
pm_options_scope_init(options_scope, locals_count);
|
||||||
|
|
||||||
|
uint8_t forwarding = PM_OPTIONS_SCOPE_FORWARDING_NONE;
|
||||||
|
|
||||||
for (int local_index = 0; local_index < locals_count; local_index++) {
|
for (int local_index = 0; local_index < locals_count; local_index++) {
|
||||||
pm_string_t *scope_local = &options_scope->locals[local_index];
|
pm_string_t *scope_local = &options_scope->locals[local_index];
|
||||||
ID local = ISEQ_BODY(iseq)->local_table[local_index];
|
ID local = ISEQ_BODY(iseq)->local_table[local_index];
|
||||||
@ -1729,10 +1741,23 @@ pm_eval_make_iseq(VALUE src, VALUE fname, int line,
|
|||||||
|
|
||||||
RB_GC_GUARD(name_obj);
|
RB_GC_GUARD(name_obj);
|
||||||
|
|
||||||
pm_string_owned_init(scope_local, (uint8_t *)name_dup, length);
|
pm_string_owned_init(scope_local, (uint8_t *) name_dup, length);
|
||||||
|
} else if (local == idMULT) {
|
||||||
|
forwarding |= PM_OPTIONS_SCOPE_FORWARDING_POSITIONALS;
|
||||||
|
pm_string_constant_init(scope_local, FORWARDING_POSITIONALS_STR, 1);
|
||||||
|
} else if (local == idPow) {
|
||||||
|
forwarding |= PM_OPTIONS_SCOPE_FORWARDING_KEYWORDS;
|
||||||
|
pm_string_constant_init(scope_local, FORWARDING_KEYWORDS_STR, 1);
|
||||||
|
} else if (local == idAnd) {
|
||||||
|
forwarding |= PM_OPTIONS_SCOPE_FORWARDING_BLOCK;
|
||||||
|
pm_string_constant_init(scope_local, FORWARDING_BLOCK_STR, 1);
|
||||||
|
} else if (local == idDot3) {
|
||||||
|
forwarding |= PM_OPTIONS_SCOPE_FORWARDING_ALL;
|
||||||
|
pm_string_constant_init(scope_local, FORWARDING_ALL_STR, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pm_options_scope_forwarding_set(options_scope, forwarding);
|
||||||
iseq = ISEQ_BODY(iseq)->parent_iseq;
|
iseq = ISEQ_BODY(iseq)->parent_iseq;
|
||||||
|
|
||||||
/* We need to GC guard the iseq because the code above malloc memory
|
/* We need to GC guard the iseq because the code above malloc memory
|
||||||
@ -1775,14 +1800,38 @@ pm_eval_make_iseq(VALUE src, VALUE fname, int line,
|
|||||||
|
|
||||||
for (int local_index = 0; local_index < locals_count; local_index++) {
|
for (int local_index = 0; local_index < locals_count; local_index++) {
|
||||||
const pm_string_t *scope_local = &options_scope->locals[local_index];
|
const pm_string_t *scope_local = &options_scope->locals[local_index];
|
||||||
|
|
||||||
pm_constant_id_t constant_id = 0;
|
pm_constant_id_t constant_id = 0;
|
||||||
if (pm_string_length(scope_local) > 0) {
|
|
||||||
constant_id = pm_constant_pool_insert_constant(
|
const uint8_t *source = pm_string_source(scope_local);
|
||||||
&result.parser.constant_pool, pm_string_source(scope_local),
|
size_t length = pm_string_length(scope_local);
|
||||||
pm_string_length(scope_local));
|
|
||||||
st_insert(parent_scope->index_lookup_table, (st_data_t)constant_id, (st_data_t)local_index);
|
if (length > 0) {
|
||||||
|
if (length == 1) {
|
||||||
|
switch (*source) {
|
||||||
|
case FORWARDING_POSITIONALS_CHR:
|
||||||
|
constant_id = PM_CONSTANT_MULT;
|
||||||
|
break;
|
||||||
|
case FORWARDING_KEYWORDS_CHR:
|
||||||
|
constant_id = PM_CONSTANT_POW;
|
||||||
|
break;
|
||||||
|
case FORWARDING_BLOCK_CHR:
|
||||||
|
constant_id = PM_CONSTANT_AND;
|
||||||
|
break;
|
||||||
|
case FORWARDING_ALL_CHR:
|
||||||
|
constant_id = PM_CONSTANT_DOT3;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
constant_id = pm_constant_pool_insert_constant(&result.parser.constant_pool, source, length);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
constant_id = pm_constant_pool_insert_constant(&result.parser.constant_pool, source, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
st_insert(parent_scope->index_lookup_table, (st_data_t) constant_id, (st_data_t) local_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
pm_constant_id_list_append(&parent_scope->locals, constant_id);
|
pm_constant_id_list_append(&parent_scope->locals, constant_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1791,6 +1840,15 @@ pm_eval_make_iseq(VALUE src, VALUE fname, int line,
|
|||||||
iseq = ISEQ_BODY(iseq)->parent_iseq;
|
iseq = ISEQ_BODY(iseq)->parent_iseq;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#undef FORWARDING_POSITIONALS_CHR
|
||||||
|
#undef FORWARDING_POSITIONALS_STR
|
||||||
|
#undef FORWARDING_KEYWORDS_CHR
|
||||||
|
#undef FORWARDING_KEYWORDS_STR
|
||||||
|
#undef FORWARDING_BLOCK_CHR
|
||||||
|
#undef FORWARDING_BLOCK_STR
|
||||||
|
#undef FORWARDING_ALL_CHR
|
||||||
|
#undef FORWARDING_ALL_STR
|
||||||
|
|
||||||
int error_state;
|
int error_state;
|
||||||
iseq = pm_iseq_new_eval(&result.node, name, fname, Qnil, line, parent, 0, &error_state);
|
iseq = pm_iseq_new_eval(&result.node, name, fname, Qnil, line, parent, 0, &error_state);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user