Introduce Numeric Node's

This commit is contained in:
S-H-GAMELINKS 2024-01-05 12:03:11 +09:00 committed by Yuichiro Kaneko
parent 76afbda5b5
commit 1b8d01136c
13 changed files with 595 additions and 92 deletions

8
ast.c
View File

@ -558,6 +558,14 @@ node_children(rb_ast_t *ast, const NODE *node)
case NODE_STR:
case NODE_XSTR:
return rb_ary_new_from_args(1, RNODE_LIT(node)->nd_lit);
case NODE_INTEGER:
return rb_ary_new_from_args(1, rb_node_integer_literal_val(RNODE_INTEGER(node)));
case NODE_FLOAT:
return rb_ary_new_from_args(1, rb_node_float_literal_val(RNODE_FLOAT(node)));
case NODE_RATIONAL:
return rb_ary_new_from_args(1, rb_node_rational_literal_val(RNODE_RATIONAL(node)));
case NODE_IMAGINARY:
return rb_ary_new_from_args(1, rb_node_imaginary_literal_val(RNODE_IMAGINARY(node)));
case NODE_ONCE:
return rb_ary_new_from_node_args(ast, 1, RNODE_ONCE(node)->nd_body);
case NODE_DSTR:

View File

@ -2200,10 +2200,16 @@ ast.$(OBJEXT): $(hdrdir)/ruby.h
ast.$(OBJEXT): $(hdrdir)/ruby/ruby.h
ast.$(OBJEXT): $(top_srcdir)/internal/array.h
ast.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
ast.$(OBJEXT): $(top_srcdir)/internal/bignum.h
ast.$(OBJEXT): $(top_srcdir)/internal/bits.h
ast.$(OBJEXT): $(top_srcdir)/internal/compilers.h
ast.$(OBJEXT): $(top_srcdir)/internal/complex.h
ast.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
ast.$(OBJEXT): $(top_srcdir)/internal/gc.h
ast.$(OBJEXT): $(top_srcdir)/internal/imemo.h
ast.$(OBJEXT): $(top_srcdir)/internal/numeric.h
ast.$(OBJEXT): $(top_srcdir)/internal/parse.h
ast.$(OBJEXT): $(top_srcdir)/internal/rational.h
ast.$(OBJEXT): $(top_srcdir)/internal/ruby_parser.h
ast.$(OBJEXT): $(top_srcdir)/internal/serial.h
ast.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
@ -7416,9 +7422,15 @@ goruby.$(OBJEXT): $(hdrdir)/ruby.h
goruby.$(OBJEXT): $(hdrdir)/ruby/ruby.h
goruby.$(OBJEXT): $(top_srcdir)/internal/array.h
goruby.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
goruby.$(OBJEXT): $(top_srcdir)/internal/bignum.h
goruby.$(OBJEXT): $(top_srcdir)/internal/bits.h
goruby.$(OBJEXT): $(top_srcdir)/internal/compilers.h
goruby.$(OBJEXT): $(top_srcdir)/internal/complex.h
goruby.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
goruby.$(OBJEXT): $(top_srcdir)/internal/gc.h
goruby.$(OBJEXT): $(top_srcdir)/internal/imemo.h
goruby.$(OBJEXT): $(top_srcdir)/internal/numeric.h
goruby.$(OBJEXT): $(top_srcdir)/internal/rational.h
goruby.$(OBJEXT): $(top_srcdir)/internal/ruby_parser.h
goruby.$(OBJEXT): $(top_srcdir)/internal/serial.h
goruby.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
@ -8469,16 +8481,21 @@ iseq.$(OBJEXT): $(hdrdir)/ruby/ruby.h
iseq.$(OBJEXT): $(hdrdir)/ruby/version.h
iseq.$(OBJEXT): $(top_srcdir)/internal/array.h
iseq.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
iseq.$(OBJEXT): $(top_srcdir)/internal/bignum.h
iseq.$(OBJEXT): $(top_srcdir)/internal/bits.h
iseq.$(OBJEXT): $(top_srcdir)/internal/class.h
iseq.$(OBJEXT): $(top_srcdir)/internal/compile.h
iseq.$(OBJEXT): $(top_srcdir)/internal/compilers.h
iseq.$(OBJEXT): $(top_srcdir)/internal/complex.h
iseq.$(OBJEXT): $(top_srcdir)/internal/error.h
iseq.$(OBJEXT): $(top_srcdir)/internal/file.h
iseq.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
iseq.$(OBJEXT): $(top_srcdir)/internal/gc.h
iseq.$(OBJEXT): $(top_srcdir)/internal/hash.h
iseq.$(OBJEXT): $(top_srcdir)/internal/imemo.h
iseq.$(OBJEXT): $(top_srcdir)/internal/numeric.h
iseq.$(OBJEXT): $(top_srcdir)/internal/parse.h
iseq.$(OBJEXT): $(top_srcdir)/internal/rational.h
iseq.$(OBJEXT): $(top_srcdir)/internal/ruby_parser.h
iseq.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
iseq.$(OBJEXT): $(top_srcdir)/internal/serial.h
@ -8719,16 +8736,21 @@ load.$(OBJEXT): $(hdrdir)/ruby/ruby.h
load.$(OBJEXT): $(hdrdir)/ruby/version.h
load.$(OBJEXT): $(top_srcdir)/internal/array.h
load.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
load.$(OBJEXT): $(top_srcdir)/internal/bignum.h
load.$(OBJEXT): $(top_srcdir)/internal/bits.h
load.$(OBJEXT): $(top_srcdir)/internal/compilers.h
load.$(OBJEXT): $(top_srcdir)/internal/complex.h
load.$(OBJEXT): $(top_srcdir)/internal/dir.h
load.$(OBJEXT): $(top_srcdir)/internal/error.h
load.$(OBJEXT): $(top_srcdir)/internal/file.h
load.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
load.$(OBJEXT): $(top_srcdir)/internal/gc.h
load.$(OBJEXT): $(top_srcdir)/internal/hash.h
load.$(OBJEXT): $(top_srcdir)/internal/imemo.h
load.$(OBJEXT): $(top_srcdir)/internal/load.h
load.$(OBJEXT): $(top_srcdir)/internal/numeric.h
load.$(OBJEXT): $(top_srcdir)/internal/parse.h
load.$(OBJEXT): $(top_srcdir)/internal/rational.h
load.$(OBJEXT): $(top_srcdir)/internal/ruby_parser.h
load.$(OBJEXT): $(top_srcdir)/internal/serial.h
load.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
@ -10044,9 +10066,15 @@ miniinit.$(OBJEXT): $(hdrdir)/ruby/ruby.h
miniinit.$(OBJEXT): $(srcdir)/rjit_c.rb
miniinit.$(OBJEXT): $(top_srcdir)/internal/array.h
miniinit.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
miniinit.$(OBJEXT): $(top_srcdir)/internal/bignum.h
miniinit.$(OBJEXT): $(top_srcdir)/internal/bits.h
miniinit.$(OBJEXT): $(top_srcdir)/internal/compilers.h
miniinit.$(OBJEXT): $(top_srcdir)/internal/complex.h
miniinit.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
miniinit.$(OBJEXT): $(top_srcdir)/internal/gc.h
miniinit.$(OBJEXT): $(top_srcdir)/internal/imemo.h
miniinit.$(OBJEXT): $(top_srcdir)/internal/numeric.h
miniinit.$(OBJEXT): $(top_srcdir)/internal/rational.h
miniinit.$(OBJEXT): $(top_srcdir)/internal/ruby_parser.h
miniinit.$(OBJEXT): $(top_srcdir)/internal/serial.h
miniinit.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
@ -10492,10 +10520,16 @@ node_dump.$(OBJEXT): $(CCAN_DIR)/str/str.h
node_dump.$(OBJEXT): $(hdrdir)/ruby/ruby.h
node_dump.$(OBJEXT): $(top_srcdir)/internal/array.h
node_dump.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
node_dump.$(OBJEXT): $(top_srcdir)/internal/bignum.h
node_dump.$(OBJEXT): $(top_srcdir)/internal/bits.h
node_dump.$(OBJEXT): $(top_srcdir)/internal/compilers.h
node_dump.$(OBJEXT): $(top_srcdir)/internal/complex.h
node_dump.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
node_dump.$(OBJEXT): $(top_srcdir)/internal/gc.h
node_dump.$(OBJEXT): $(top_srcdir)/internal/hash.h
node_dump.$(OBJEXT): $(top_srcdir)/internal/imemo.h
node_dump.$(OBJEXT): $(top_srcdir)/internal/numeric.h
node_dump.$(OBJEXT): $(top_srcdir)/internal/rational.h
node_dump.$(OBJEXT): $(top_srcdir)/internal/ruby_parser.h
node_dump.$(OBJEXT): $(top_srcdir)/internal/serial.h
node_dump.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
@ -15587,12 +15621,16 @@ ruby.$(OBJEXT): $(hdrdir)/ruby/ruby.h
ruby.$(OBJEXT): $(hdrdir)/ruby/version.h
ruby.$(OBJEXT): $(top_srcdir)/internal/array.h
ruby.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
ruby.$(OBJEXT): $(top_srcdir)/internal/bignum.h
ruby.$(OBJEXT): $(top_srcdir)/internal/bits.h
ruby.$(OBJEXT): $(top_srcdir)/internal/class.h
ruby.$(OBJEXT): $(top_srcdir)/internal/cmdlineopt.h
ruby.$(OBJEXT): $(top_srcdir)/internal/compilers.h
ruby.$(OBJEXT): $(top_srcdir)/internal/complex.h
ruby.$(OBJEXT): $(top_srcdir)/internal/cont.h
ruby.$(OBJEXT): $(top_srcdir)/internal/error.h
ruby.$(OBJEXT): $(top_srcdir)/internal/file.h
ruby.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
ruby.$(OBJEXT): $(top_srcdir)/internal/gc.h
ruby.$(OBJEXT): $(top_srcdir)/internal/imemo.h
ruby.$(OBJEXT): $(top_srcdir)/internal/inits.h
@ -15600,8 +15638,10 @@ ruby.$(OBJEXT): $(top_srcdir)/internal/io.h
ruby.$(OBJEXT): $(top_srcdir)/internal/load.h
ruby.$(OBJEXT): $(top_srcdir)/internal/loadpath.h
ruby.$(OBJEXT): $(top_srcdir)/internal/missing.h
ruby.$(OBJEXT): $(top_srcdir)/internal/numeric.h
ruby.$(OBJEXT): $(top_srcdir)/internal/object.h
ruby.$(OBJEXT): $(top_srcdir)/internal/parse.h
ruby.$(OBJEXT): $(top_srcdir)/internal/rational.h
ruby.$(OBJEXT): $(top_srcdir)/internal/ruby_parser.h
ruby.$(OBJEXT): $(top_srcdir)/internal/serial.h
ruby.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
@ -15828,7 +15868,14 @@ ruby.$(OBJEXT): {$(VPATH)}vm_opts.h
ruby.$(OBJEXT): {$(VPATH)}yjit.h
ruby_parser.$(OBJEXT): $(hdrdir)/ruby/ruby.h
ruby_parser.$(OBJEXT): $(top_srcdir)/internal/array.h
ruby_parser.$(OBJEXT): $(top_srcdir)/internal/bignum.h
ruby_parser.$(OBJEXT): $(top_srcdir)/internal/bits.h
ruby_parser.$(OBJEXT): $(top_srcdir)/internal/compilers.h
ruby_parser.$(OBJEXT): $(top_srcdir)/internal/complex.h
ruby_parser.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
ruby_parser.$(OBJEXT): $(top_srcdir)/internal/imemo.h
ruby_parser.$(OBJEXT): $(top_srcdir)/internal/numeric.h
ruby_parser.$(OBJEXT): $(top_srcdir)/internal/rational.h
ruby_parser.$(OBJEXT): $(top_srcdir)/internal/ruby_parser.h
ruby_parser.$(OBJEXT): $(top_srcdir)/internal/serial.h
ruby_parser.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
@ -15837,6 +15884,7 @@ ruby_parser.$(OBJEXT): {$(VPATH)}assert.h
ruby_parser.$(OBJEXT): {$(VPATH)}backward/2/assume.h
ruby_parser.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
ruby_parser.$(OBJEXT): {$(VPATH)}backward/2/bool.h
ruby_parser.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
ruby_parser.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
ruby_parser.$(OBJEXT): {$(VPATH)}backward/2/limits.h
ruby_parser.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
@ -15998,6 +16046,7 @@ ruby_parser.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
ruby_parser.$(OBJEXT): {$(VPATH)}missing.h
ruby_parser.$(OBJEXT): {$(VPATH)}onigmo.h
ruby_parser.$(OBJEXT): {$(VPATH)}oniguruma.h
ruby_parser.$(OBJEXT): {$(VPATH)}ruby_assert.h
ruby_parser.$(OBJEXT): {$(VPATH)}ruby_parser.c
ruby_parser.$(OBJEXT): {$(VPATH)}rubyparser.h
ruby_parser.$(OBJEXT): {$(VPATH)}st.h
@ -19259,6 +19308,7 @@ vm.$(OBJEXT): $(top_srcdir)/internal/class.h
vm.$(OBJEXT): $(top_srcdir)/internal/compar.h
vm.$(OBJEXT): $(top_srcdir)/internal/compile.h
vm.$(OBJEXT): $(top_srcdir)/internal/compilers.h
vm.$(OBJEXT): $(top_srcdir)/internal/complex.h
vm.$(OBJEXT): $(top_srcdir)/internal/cont.h
vm.$(OBJEXT): $(top_srcdir)/internal/encoding.h
vm.$(OBJEXT): $(top_srcdir)/internal/error.h
@ -19273,6 +19323,7 @@ vm.$(OBJEXT): $(top_srcdir)/internal/object.h
vm.$(OBJEXT): $(top_srcdir)/internal/parse.h
vm.$(OBJEXT): $(top_srcdir)/internal/proc.h
vm.$(OBJEXT): $(top_srcdir)/internal/random.h
vm.$(OBJEXT): $(top_srcdir)/internal/rational.h
vm.$(OBJEXT): $(top_srcdir)/internal/re.h
vm.$(OBJEXT): $(top_srcdir)/internal/ruby_parser.h
vm.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h

109
compile.c
View File

@ -1944,6 +1944,17 @@ iseq_set_arguments_keywords(rb_iseq_t *iseq, LINK_ANCHOR *const optargs,
break;
case NODE_LINE:
dv = rb_node_line_lineno_val(val_node);;
case NODE_INTEGER:
dv = rb_node_integer_literal_val(RNODE_INTEGER(val_node));
break;
case NODE_FLOAT:
dv = rb_node_float_literal_val(RNODE_FLOAT(val_node));
break;
case NODE_RATIONAL:
dv = rb_node_rational_literal_val(RNODE_RATIONAL(val_node));
break;
case NODE_IMAGINARY:
dv = rb_node_imaginary_literal_val(RNODE_IMAGINARY(val_node));
break;
case NODE_NIL:
dv = Qnil;
@ -4506,6 +4517,10 @@ compile_branch_condition(rb_iseq_t *iseq, LINK_ANCHOR *ret, const NODE *cond,
case NODE_LIT: /* NODE_LIT is always true */
case NODE_LINE:
case NODE_FILE:
case NODE_INTEGER: /* NODE_INTEGER is always true */
case NODE_FLOAT: /* NODE_FLOAT is always true */
case NODE_RATIONAL: /* NODE_RATIONAL is always true */
case NODE_IMAGINARY: /* NODE_IMAGINARY is always true */
case NODE_TRUE:
case NODE_STR:
case NODE_ZLIST:
@ -4666,6 +4681,10 @@ static_literal_node_p(const NODE *node, const rb_iseq_t *iseq)
switch (nd_type(node)) {
case NODE_LIT:
case NODE_LINE:
case NODE_INTEGER:
case NODE_FLOAT:
case NODE_RATIONAL:
case NODE_IMAGINARY:
case NODE_NIL:
case NODE_TRUE:
case NODE_FALSE:
@ -4682,6 +4701,14 @@ static inline VALUE
static_literal_value(const NODE *node, rb_iseq_t *iseq)
{
switch (nd_type(node)) {
case NODE_INTEGER:
return rb_node_integer_literal_val(RNODE_INTEGER(node));
case NODE_FLOAT:
return rb_node_float_literal_val(RNODE_FLOAT(node));
case NODE_RATIONAL:
return rb_node_rational_literal_val(RNODE_RATIONAL(node));
case NODE_IMAGINARY:
return rb_node_imaginary_literal_val(RNODE_IMAGINARY(node));
case NODE_NIL:
return Qnil;
case NODE_TRUE:
@ -5059,19 +5086,25 @@ rb_node_case_when_optimizable_literal(const NODE *const node)
switch (nd_type(node)) {
case NODE_LIT: {
VALUE v = RNODE_LIT(node)->nd_lit;
double ival;
if (RB_FLOAT_TYPE_P(v) &&
modf(RFLOAT_VALUE(v), &ival) == 0.0) {
return FIXABLE(ival) ? LONG2FIX((long)ival) : rb_dbl2big(ival);
}
if (RB_TYPE_P(v, T_RATIONAL) || RB_TYPE_P(v, T_COMPLEX)) {
return Qundef;
}
if (SYMBOL_P(v) || rb_obj_is_kind_of(v, rb_cNumeric)) {
if (SYMBOL_P(v)) {
return v;
}
break;
}
case NODE_INTEGER:
return rb_node_integer_literal_val(RNODE_INTEGER(node));
case NODE_FLOAT: {
VALUE v = rb_node_float_literal_val(RNODE_FLOAT(node));
double ival;
if (modf(RFLOAT_VALUE(v), &ival) == 0.0) {
return FIXABLE(ival) ? LONG2FIX((long)ival) : rb_dbl2big(ival);
}
return v;
}
case NODE_RATIONAL:
case NODE_IMAGINARY:
return Qundef;
case NODE_NIL:
return Qnil;
case NODE_TRUE:
@ -5710,6 +5743,10 @@ defined_expr0(rb_iseq_t *iseq, LINK_ANCHOR *const ret,
case NODE_LIT:
case NODE_LINE:
case NODE_FILE:
case NODE_INTEGER:
case NODE_FLOAT:
case NODE_RATIONAL:
case NODE_IMAGINARY:
case NODE_ZLIST:
case NODE_AND:
case NODE_OR:
@ -6286,6 +6323,8 @@ optimizable_range_item_p(const NODE *n)
return RB_INTEGER_TYPE_P(RNODE_LIT(n)->nd_lit);
case NODE_LINE:
return TRUE;
case NODE_INTEGER:
return TRUE;
case NODE_NIL:
return TRUE;
default:
@ -6301,6 +6340,14 @@ optimized_range_item(const NODE *n)
return RNODE_LIT(n)->nd_lit;
case NODE_LINE:
return rb_node_line_lineno_val(n);
case NODE_INTEGER:
return rb_node_integer_literal_val(RNODE_INTEGER(n));
case NODE_FLOAT:
return rb_node_float_literal_val(RNODE_FLOAT(n));
case NODE_RATIONAL:
return rb_node_rational_literal_val(RNODE_RATIONAL(n));
case NODE_IMAGINARY:
return rb_node_imaginary_literal_val(RNODE_IMAGINARY(n));
case NODE_NIL:
return Qnil;
default:
@ -7123,6 +7170,10 @@ iseq_compile_pattern_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *c
}
case NODE_LIT:
case NODE_LINE:
case NODE_INTEGER:
case NODE_FLOAT:
case NODE_RATIONAL:
case NODE_IMAGINARY:
case NODE_FILE:
case NODE_STR:
case NODE_XSTR:
@ -9679,6 +9730,10 @@ compile_kw_arg(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node,
}
else if (nd_type_p(default_value, NODE_LIT) ||
nd_type_p(default_value, NODE_LINE) ||
nd_type_p(default_value, NODE_INTEGER) ||
nd_type_p(default_value, NODE_FLOAT) ||
nd_type_p(default_value, NODE_RATIONAL) ||
nd_type_p(default_value, NODE_IMAGINARY) ||
nd_type_p(default_value, NODE_NIL) ||
nd_type_p(default_value, NODE_TRUE) ||
nd_type_p(default_value, NODE_FALSE)) {
@ -10154,6 +10209,42 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no
}
break;
}
case NODE_INTEGER:{
VALUE lit = rb_node_integer_literal_val(RNODE_INTEGER(node));
debugp_param("integer", lit);
if (!popped) {
ADD_INSN1(ret, node, putobject, lit);
RB_OBJ_WRITTEN(iseq, Qundef, lit);
}
break;
}
case NODE_FLOAT:{
VALUE lit = rb_node_float_literal_val(RNODE_FLOAT(node));
debugp_param("float", lit);
if (!popped) {
ADD_INSN1(ret, node, putobject, lit);
RB_OBJ_WRITTEN(iseq, Qundef, lit);
}
break;
}
case NODE_RATIONAL:{
VALUE lit = rb_node_rational_literal_val(RNODE_RATIONAL(node));
debugp_param("rational", lit);
if (!popped) {
ADD_INSN1(ret, node, putobject, lit);
RB_OBJ_WRITTEN(iseq, Qundef, lit);
}
break;
}
case NODE_IMAGINARY:{
VALUE lit = rb_node_imaginary_literal_val(RNODE_IMAGINARY(node));
debugp_param("imaginary", lit);
if (!popped) {
ADD_INSN1(ret, node, putobject, lit);
RB_OBJ_WRITTEN(iseq, Qundef, lit);
}
break;
}
case NODE_FILE:
case NODE_STR:{
debugp_param("nd_lit", get_string_value(node));

View File

@ -634,6 +634,7 @@ ripper_init.o: $(hdrdir)/ruby/backward.h
ripper_init.o: $(hdrdir)/ruby/backward/2/assume.h
ripper_init.o: $(hdrdir)/ruby/backward/2/attributes.h
ripper_init.o: $(hdrdir)/ruby/backward/2/bool.h
ripper_init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
ripper_init.o: $(hdrdir)/ruby/backward/2/inttypes.h
ripper_init.o: $(hdrdir)/ruby/backward/2/limits.h
ripper_init.o: $(hdrdir)/ruby/backward/2/long_long.h
@ -798,13 +799,21 @@ ripper_init.o: $(hdrdir)/ruby/st.h
ripper_init.o: $(hdrdir)/ruby/subst.h
ripper_init.o: $(top_srcdir)/internal.h
ripper_init.o: $(top_srcdir)/internal/array.h
ripper_init.o: $(top_srcdir)/internal/bignum.h
ripper_init.o: $(top_srcdir)/internal/bits.h
ripper_init.o: $(top_srcdir)/internal/compilers.h
ripper_init.o: $(top_srcdir)/internal/complex.h
ripper_init.o: $(top_srcdir)/internal/fixnum.h
ripper_init.o: $(top_srcdir)/internal/imemo.h
ripper_init.o: $(top_srcdir)/internal/numeric.h
ripper_init.o: $(top_srcdir)/internal/parse.h
ripper_init.o: $(top_srcdir)/internal/rational.h
ripper_init.o: $(top_srcdir)/internal/ruby_parser.h
ripper_init.o: $(top_srcdir)/internal/serial.h
ripper_init.o: $(top_srcdir)/internal/static_assert.h
ripper_init.o: $(top_srcdir)/internal/vm.h
ripper_init.o: $(top_srcdir)/node.h
ripper_init.o: $(top_srcdir)/ruby_assert.h
ripper_init.o: $(top_srcdir)/rubyparser.h
ripper_init.o: eventids1.h
ripper_init.o: eventids2.h

View File

@ -2,7 +2,11 @@
#define INTERNAL_RUBY_PARSE_H
#include "internal.h"
#include "internal/bignum.h"
#include "internal/compilers.h"
#include "internal/complex.h"
#include "internal/imemo.h"
#include "internal/rational.h"
#include "rubyparser.h"
#include "vm.h"
@ -69,4 +73,10 @@ enum lex_state_e {
VALUE rb_node_line_lineno_val(const NODE *);
VALUE rb_node_file_path_val(const NODE *);
VALUE rb_node_integer_literal_val(rb_node_integer_t* node);
VALUE rb_node_float_literal_val(rb_node_float_t* node);
VALUE rb_node_rational_literal_val(rb_node_rational_t* node);
VALUE rb_node_imaginary_literal_val(rb_node_imaginary_t* node);
#endif /* INTERNAL_RUBY_PARSE_H */

12
node.c
View File

@ -182,6 +182,18 @@ free_ast_value(rb_ast_t *ast, void *ctx, NODE *node)
case NODE_FILE:
parser_string_free(ast, RNODE_FILE(node)->path);
break;
case NODE_INTEGER:
xfree(RNODE_INTEGER(node)->val);
break;
case NODE_FLOAT:
xfree(RNODE_FLOAT(node)->val);
break;
case NODE_RATIONAL:
xfree(RNODE_RATIONAL(node)->val);
break;
case NODE_IMAGINARY:
xfree(RNODE_IMAGINARY(node)->val);
break;
default:
break;
}

View File

@ -706,7 +706,7 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node)
case NODE_LIT:
ANN("literal");
ANN("format: [nd_lit]");
ANN("example: 1, /foo/");
ANN("example: :sym, /foo/");
goto lit;
case NODE_STR:
ANN("string literal");
@ -721,6 +721,34 @@ dump_node(VALUE buf, VALUE indent, int comment, const NODE * node)
F_LIT(nd_lit, RNODE_LIT, "literal");
return;
case NODE_INTEGER:
ANN("integer literal");
ANN("format: [val]");
ANN("example: 1");
F_VALUE(val, rb_node_integer_literal_val(RNODE_INTEGER(node)), "val");
return;
case NODE_FLOAT:
ANN("float literal");
ANN("format: [val]");
ANN("example: 1.2");
F_VALUE(val, rb_node_float_literal_val(RNODE_FLOAT(node)), "val");
return;
case NODE_RATIONAL:
ANN("rational number literal");
ANN("format: [val]");
ANN("example: 1r");
F_VALUE(val, rb_node_rational_literal_val(RNODE_RATIONAL(node)), "val");
return;
case NODE_IMAGINARY:
ANN("complex number literal");
ANN("format: [val]");
ANN("example: 1i");
F_VALUE(val, rb_node_imaginary_literal_val(RNODE_IMAGINARY(node)), "val");
return;
case NODE_ONCE:
ANN("once evaluation");
ANN("format: [nd_body]");

259
parse.y
View File

@ -912,6 +912,10 @@ static rb_node_back_ref_t *rb_node_back_ref_new(struct parser_params *p, long nd
static rb_node_match2_t *rb_node_match2_new(struct parser_params *p, NODE *nd_recv, NODE *nd_value, const YYLTYPE *loc);
static rb_node_match3_t *rb_node_match3_new(struct parser_params *p, NODE *nd_recv, NODE *nd_value, const YYLTYPE *loc);
static rb_node_lit_t *rb_node_lit_new(struct parser_params *p, VALUE nd_lit, const YYLTYPE *loc);
static rb_node_integer_t * rb_node_integer_new(struct parser_params *p, char* val, int base, const YYLTYPE *loc);
static rb_node_float_t * rb_node_float_new(struct parser_params *p, char* val, const YYLTYPE *loc);
static rb_node_rational_t * rb_node_rational_new(struct parser_params *p, char* val, int base, int seen_point, const YYLTYPE *loc);
static rb_node_imaginary_t * rb_node_imaginary_new(struct parser_params *p, char* val, int base, int seen_point, enum rb_numeric_type, const YYLTYPE *loc);
static rb_node_str_t *rb_node_str_new(struct parser_params *p, VALUE nd_lit, const YYLTYPE *loc);
static rb_node_dstr_t *rb_node_dstr_new0(struct parser_params *p, VALUE nd_lit, long nd_alen, NODE *nd_next, const YYLTYPE *loc);
static rb_node_dstr_t *rb_node_dstr_new(struct parser_params *p, VALUE nd_lit, const YYLTYPE *loc);
@ -1015,6 +1019,10 @@ static rb_node_error_t *rb_node_error_new(struct parser_params *p, const YYLTYPE
#define NEW_MATCH2(n1,n2,loc) (NODE *)rb_node_match2_new(p,n1,n2,loc)
#define NEW_MATCH3(r,n2,loc) (NODE *)rb_node_match3_new(p,r,n2,loc)
#define NEW_LIT(l,loc) (NODE *)rb_node_lit_new(p,l,loc)
#define NEW_INTEGER(val, base,loc) (NODE *)rb_node_integer_new(p,val,base,loc)
#define NEW_FLOAT(val,loc) (NODE *)rb_node_float_new(p,val,loc)
#define NEW_RATIONAL(val,base,seen_point,loc) (NODE *)rb_node_rational_new(p,val,base,seen_point,loc)
#define NEW_IMAGINARY(val,base,seen_point,numeric_type,loc) (NODE *)rb_node_imaginary_new(p,val,base,seen_point,numeric_type,loc)
#define NEW_STR(s,loc) (NODE *)rb_node_str_new(p,s,loc)
#define NEW_DSTR0(s,l,n,loc) (NODE *)rb_node_dstr_new0(p,s,l,n,loc)
#define NEW_DSTR(s,loc) (NODE *)rb_node_dstr_new(p,s,loc)
@ -1230,7 +1238,7 @@ static NODE *new_hash_pattern_tail(struct parser_params *p, NODE *kw_args, ID kw
static rb_node_kw_arg_t *new_kw_arg(struct parser_params *p, NODE *k, const YYLTYPE *loc);
static rb_node_args_t *args_with_numbered(struct parser_params*,rb_node_args_t*,int,ID);
static VALUE negate_lit(struct parser_params*, VALUE);
static NODE* negate_lit(struct parser_params*, NODE*);
static NODE *ret_args(struct parser_params*,NODE*);
static NODE *arg_blk_pass(NODE*,rb_node_block_pass_t*);
static NODE *new_yield(struct parser_params*,NODE*,const YYLTYPE*);
@ -6074,7 +6082,7 @@ numeric : simple_numeric
{
/*%%%*/
$$ = $2;
RB_OBJ_WRITE(p->ast, &RNODE_LIT($$)->nd_lit, negate_lit(p, RNODE_LIT($$)->nd_lit));
negate_lit(p, $$);
/*% %*/
/*% ripper: unary!(ID2VAL(idUMinus), $2) %*/
}
@ -6652,6 +6660,10 @@ singleton : var_ref
case NODE_LIT:
case NODE_LINE:
case NODE_FILE:
case NODE_INTEGER:
case NODE_FLOAT:
case NODE_RATIONAL:
case NODE_IMAGINARY:
case NODE_DSYM:
case NODE_LIST:
case NODE_ZLIST:
@ -8990,29 +9002,42 @@ number_literal_suffix(struct parser_params *p, int mask)
}
static enum yytokentype
set_number_literal(struct parser_params *p, VALUE v,
enum yytokentype type, int suffix)
set_number_literal(struct parser_params *p, enum yytokentype type, int suffix, int base, int seen_point)
{
enum rb_numeric_type numeric_type = integer_literal;
if (type == tFLOAT) {
numeric_type = float_literal;
}
if (suffix & NUM_SUFFIX_R) {
type = tRATIONAL;
numeric_type = rational_literal;
}
if (suffix & NUM_SUFFIX_I) {
v = rb_complex_raw(INT2FIX(0), v);
type = tIMAGINARY;
}
set_yylval_literal(v);
switch (type) {
case tINTEGER:
set_yylval_node(NEW_INTEGER(strdup(tok(p)), base, &_cur_loc));
break;
case tFLOAT:
set_yylval_node(NEW_FLOAT(strdup(tok(p)), &_cur_loc));
break;
case tRATIONAL:
set_yylval_node(NEW_RATIONAL(strdup(tok(p)), base, seen_point, &_cur_loc));
break;
case tIMAGINARY:
set_yylval_node(NEW_IMAGINARY(strdup(tok(p)), base, seen_point, numeric_type, &_cur_loc));
break;
default:
rb_bug("unexpected token: %d", type);
}
SET_LEX_STATE(EXPR_END);
return type;
}
static enum yytokentype
set_integer_literal(struct parser_params *p, VALUE v, int suffix)
{
enum yytokentype type = tINTEGER;
if (suffix & NUM_SUFFIX_R) {
v = rb_rational_raw1(v);
type = tRATIONAL;
}
return set_number_literal(p, v, type, suffix);
}
#ifdef RIPPER
static void
dispatch_heredoc_end(struct parser_params *p)
@ -9690,24 +9715,13 @@ parser_prepare(struct parser_params *p)
(ambiguous_operator(tok, op, syn), 0)), \
(enum yytokentype)(tok))
static VALUE
parse_rational(struct parser_params *p, char *str, int len, int seen_point)
{
VALUE v;
char *point = &str[seen_point];
size_t fraclen = len-seen_point-1;
memmove(point, point+1, fraclen+1);
v = rb_cstr_to_inum(str, 10, FALSE);
return rb_rational_new(v, rb_int_positive_pow(10, fraclen));
}
static enum yytokentype
no_digits(struct parser_params *p)
{
yyerror0("numeric literal without digits");
if (peek(p, '_')) nextc(p);
/* dummy 0, for tUMINUS_NUM at numeric */
return set_integer_literal(p, INT2FIX(0), 0);
return set_number_literal(p, tINTEGER, 0, 10, 0);
}
static enum yytokentype
@ -9748,7 +9762,7 @@ parse_numeric(struct parser_params *p, int c)
}
else if (nondigit) goto trailing_uc;
suffix = number_literal_suffix(p, NUM_SUFFIX_ALL);
return set_integer_literal(p, rb_cstr_to_inum(tok(p), 16, FALSE), suffix);
return set_number_literal(p, tINTEGER, suffix, 16, 0);
}
if (c == 'b' || c == 'B') {
/* binary */
@ -9772,7 +9786,7 @@ parse_numeric(struct parser_params *p, int c)
}
else if (nondigit) goto trailing_uc;
suffix = number_literal_suffix(p, NUM_SUFFIX_ALL);
return set_integer_literal(p, rb_cstr_to_inum(tok(p), 2, FALSE), suffix);
return set_number_literal(p, tINTEGER, suffix, 2, 0);
}
if (c == 'd' || c == 'D') {
/* decimal */
@ -9796,7 +9810,7 @@ parse_numeric(struct parser_params *p, int c)
}
else if (nondigit) goto trailing_uc;
suffix = number_literal_suffix(p, NUM_SUFFIX_ALL);
return set_integer_literal(p, rb_cstr_to_inum(tok(p), 10, FALSE), suffix);
return set_number_literal(p, tINTEGER, suffix, 10, 0);
}
if (c == '_') {
/* 0_0 */
@ -9828,7 +9842,7 @@ parse_numeric(struct parser_params *p, int c)
tokfix(p);
if (nondigit) goto trailing_uc;
suffix = number_literal_suffix(p, NUM_SUFFIX_ALL);
return set_integer_literal(p, rb_cstr_to_inum(tok(p), 8, FALSE), suffix);
return set_number_literal(p, tINTEGER, suffix, 8, 0);
}
if (nondigit) {
pushback(p, c);
@ -9844,8 +9858,9 @@ parse_numeric(struct parser_params *p, int c)
}
else {
pushback(p, c);
tokfix(p);
suffix = number_literal_suffix(p, NUM_SUFFIX_ALL);
return set_integer_literal(p, INT2FIX(0), suffix);
return set_number_literal(p, tINTEGER, suffix, 10, 0);
}
}
@ -9925,25 +9940,22 @@ parse_numeric(struct parser_params *p, int c)
tokfix(p);
if (is_float) {
enum yytokentype type = tFLOAT;
VALUE v;
suffix = number_literal_suffix(p, seen_e ? NUM_SUFFIX_I : NUM_SUFFIX_ALL);
if (suffix & NUM_SUFFIX_R) {
type = tRATIONAL;
v = parse_rational(p, tok(p), toklen(p), seen_point);
}
else {
double d = strtod(tok(p), 0);
strtod(tok(p), 0);
if (errno == ERANGE) {
rb_warning1("Float %s out of range", WARN_S(tok(p)));
errno = 0;
}
v = DBL2NUM(d);
}
return set_number_literal(p, v, type, suffix);
return set_number_literal(p, type, suffix, 0, seen_point);
}
suffix = number_literal_suffix(p, NUM_SUFFIX_ALL);
return set_integer_literal(p, rb_cstr_to_inum(tok(p), 10, FALSE), suffix);
return set_number_literal(p, tINTEGER, suffix, 10, 0);
}
static enum yytokentype
@ -11913,6 +11925,48 @@ rb_node_lit_new(struct parser_params *p, VALUE nd_lit, const YYLTYPE *loc)
return n;
}
static rb_node_integer_t *
rb_node_integer_new(struct parser_params *p, char* val, int base, const YYLTYPE *loc) {
rb_node_integer_t *n = NODE_NEWNODE(NODE_INTEGER, rb_node_integer_t, loc);
n->val = val;
n->minus = FALSE;
n->base = base;
return n;
}
static rb_node_float_t *
rb_node_float_new(struct parser_params *p, char* val, const YYLTYPE *loc) {
rb_node_float_t *n = NODE_NEWNODE(NODE_FLOAT, rb_node_float_t, loc);
n->val = val;
n->minus = FALSE;
return n;
}
static rb_node_rational_t *
rb_node_rational_new(struct parser_params *p, char* val, int base, int seen_point, const YYLTYPE *loc) {
rb_node_rational_t *n = NODE_NEWNODE(NODE_RATIONAL, rb_node_rational_t, loc);
n->val = val;
n->minus = FALSE;
n->base = base;
n->seen_point = seen_point;
return n;
}
static rb_node_imaginary_t *
rb_node_imaginary_new(struct parser_params *p, char* val, int base, int seen_point, enum rb_numeric_type numeric_type, const YYLTYPE *loc) {
rb_node_imaginary_t *n = NODE_NEWNODE(NODE_IMAGINARY, rb_node_imaginary_t, loc);
n->val = val;
n->minus = FALSE;
n->base = base;
n->seen_point = seen_point;
n->type = numeric_type;
return n;
}
static rb_node_str_t *
rb_node_str_new(struct parser_params *p, VALUE nd_lit, const YYLTYPE *loc)
{
@ -13709,6 +13763,14 @@ shareable_literal_value(struct parser_params *p, NODE *node)
return Qnil;
case NODE_LINE:
return rb_node_line_lineno_val(node);
case NODE_INTEGER:
return rb_node_integer_literal_val(RNODE_INTEGER(node));
case NODE_FLOAT:
return rb_node_float_literal_val(RNODE_FLOAT(node));
case NODE_RATIONAL:
return rb_node_rational_literal_val(RNODE_RATIONAL(node));
case NODE_IMAGINARY:
return rb_node_imaginary_literal_val(RNODE_IMAGINARY(node));
case NODE_LIT:
return RNODE_LIT(node)->nd_lit;
default:
@ -13736,6 +13798,10 @@ shareable_literal_constant(struct parser_params *p, enum shareability shareable,
case NODE_NIL:
case NODE_LIT:
case NODE_LINE:
case NODE_INTEGER:
case NODE_FLOAT:
case NODE_RATIONAL:
case NODE_IMAGINARY:
return value;
case NODE_DSTR:
@ -14051,6 +14117,10 @@ void_expr(struct parser_params *p, NODE *node)
case NODE_LIT:
case NODE_LINE:
case NODE_FILE:
case NODE_INTEGER:
case NODE_FLOAT:
case NODE_RATIONAL:
case NODE_IMAGINARY:
case NODE_STR:
case NODE_DSTR:
case NODE_DREGX:
@ -14190,6 +14260,10 @@ is_static_content(NODE *node)
case NODE_LIT:
case NODE_LINE:
case NODE_FILE:
case NODE_INTEGER:
case NODE_FLOAT:
case NODE_RATIONAL:
case NODE_IMAGINARY:
case NODE_STR:
case NODE_NIL:
case NODE_TRUE:
@ -14252,7 +14326,7 @@ range_op(struct parser_params *p, NODE *node, const YYLTYPE *loc)
type = nd_type(node);
value_expr(node);
if (type == NODE_LIT && FIXNUM_P(RNODE_LIT(node)->nd_lit)) {
if (type == NODE_INTEGER) {
if (!e_option_supplied(p)) parser_warn(p, node, "integer literal in flip-flop");
ID lineno = rb_intern("$.");
return NEW_CALL(node, tEQ, NEW_LIST(NEW_GVAR(lineno, loc), loc), loc);
@ -14334,6 +14408,13 @@ cond0(struct parser_params *p, NODE *node, enum cond_type type, const YYLTYPE *l
SWITCH_BY_COND_TYPE(type, warning, "");
break;
case NODE_INTEGER:
case NODE_FLOAT:
case NODE_RATIONAL:
case NODE_IMAGINARY:
SWITCH_BY_COND_TYPE(type, warning, "");
break;
default:
break;
}
@ -14431,42 +14512,24 @@ new_yield(struct parser_params *p, NODE *node, const YYLTYPE *loc)
return NEW_YIELD(node, loc);
}
static VALUE
negate_lit(struct parser_params *p, VALUE lit)
static NODE*
negate_lit(struct parser_params *p, NODE* node)
{
if (FIXNUM_P(lit)) {
return LONG2FIX(-FIX2LONG(lit));
}
if (SPECIAL_CONST_P(lit)) {
#if USE_FLONUM
if (FLONUM_P(lit)) {
return DBL2NUM(-RFLOAT_VALUE(lit));
}
#endif
goto unknown;
}
switch (BUILTIN_TYPE(lit)) {
case T_BIGNUM:
bignum_negate(lit);
lit = rb_big_norm(lit);
switch (nd_type(node)) {
case NODE_INTEGER:
RNODE_INTEGER(node)->minus = TRUE;
break;
case T_RATIONAL:
rational_set_num(lit, negate_lit(p, rational_get_num(lit)));
case NODE_FLOAT:
RNODE_FLOAT(node)->minus = TRUE;
break;
case T_COMPLEX:
rcomplex_set_real(lit, negate_lit(p, rcomplex_get_real(lit)));
rcomplex_set_imag(lit, negate_lit(p, rcomplex_get_imag(lit)));
case NODE_RATIONAL:
RNODE_RATIONAL(node)->minus = TRUE;
break;
case T_FLOAT:
lit = DBL2NUM(-RFLOAT_VALUE(lit));
break;
unknown:
default:
rb_parser_fatal(p, "unknown literal type (%s) passed to negate_lit",
rb_builtin_class_name(lit));
case NODE_IMAGINARY:
RNODE_IMAGINARY(node)->minus = TRUE;
break;
}
return lit;
return node;
}
static NODE *
@ -14754,8 +14817,60 @@ remove_duplicate_keys(struct parser_params *p, NODE *hash)
RNODE_LIST(last_expr)->nd_head = block_append(p, RNODE_LIST(dup_value)->nd_head, RNODE_LIST(last_expr)->nd_head);
}
}
else if (nd_type_p(head, NODE_INTEGER) &&
st_delete(literal_keys, (key = (st_data_t)rb_node_integer_literal_val(RNODE_INTEGER(head)), &key), &data)) {
NODE *dup_value = (RNODE_LIST((NODE *)data))->nd_next;
rb_compile_warn(p->ruby_sourcefile, nd_line((NODE *)data),
"key %+"PRIsVALUE" is duplicated and overwritten on line %d",
rb_node_integer_literal_val(RNODE_INTEGER(head)), nd_line(head));
if (dup_value == last_expr) {
RNODE_LIST(value)->nd_head = block_append(p, RNODE_LIST(dup_value)->nd_head, RNODE_LIST(value)->nd_head);
}
else {
RNODE_LIST(last_expr)->nd_head = block_append(p, RNODE_LIST(dup_value)->nd_head, RNODE_LIST(last_expr)->nd_head);
}
}
else if (nd_type_p(head, NODE_FLOAT) &&
st_delete(literal_keys, (key = (st_data_t)rb_node_float_literal_val(RNODE_FLOAT(head)), &key), &data)) {
NODE *dup_value = (RNODE_LIST((NODE *)data))->nd_next;
rb_compile_warn(p->ruby_sourcefile, nd_line((NODE *)data),
"key %+"PRIsVALUE" is duplicated and overwritten on line %d",
rb_node_float_literal_val(RNODE_FLOAT(head)), nd_line(head));
if (dup_value == last_expr) {
RNODE_LIST(value)->nd_head = block_append(p, RNODE_LIST(dup_value)->nd_head, RNODE_LIST(value)->nd_head);
}
else {
RNODE_LIST(last_expr)->nd_head = block_append(p, RNODE_LIST(dup_value)->nd_head, RNODE_LIST(last_expr)->nd_head);
}
}
else if (nd_type_p(head, NODE_RATIONAL) &&
st_delete(literal_keys, (key = (st_data_t)rb_node_rational_literal_val(RNODE_RATIONAL(head)), &key), &data)) {
NODE *dup_value = (RNODE_LIST((NODE *)data))->nd_next;
rb_compile_warn(p->ruby_sourcefile, nd_line((NODE *)data),
"key %+"PRIsVALUE" is duplicated and overwritten on line %d",
rb_node_rational_literal_val(RNODE_RATIONAL(head)), nd_line(head));
if (dup_value == last_expr) {
RNODE_LIST(value)->nd_head = block_append(p, RNODE_LIST(dup_value)->nd_head, RNODE_LIST(value)->nd_head);
}
else {
RNODE_LIST(last_expr)->nd_head = block_append(p, RNODE_LIST(dup_value)->nd_head, RNODE_LIST(last_expr)->nd_head);
}
}
else if (nd_type_p(head, NODE_IMAGINARY) &&
st_delete(literal_keys, (key = (st_data_t)rb_node_imaginary_literal_val(RNODE_IMAGINARY(head)), &key), &data)) {
NODE *dup_value = (RNODE_LIST((NODE *)data))->nd_next;
rb_compile_warn(p->ruby_sourcefile, nd_line((NODE *)data),
"key %+"PRIsVALUE" is duplicated and overwritten on line %d",
rb_node_imaginary_literal_val(RNODE_IMAGINARY(head)), nd_line(head));
if (dup_value == last_expr) {
RNODE_LIST(value)->nd_head = block_append(p, RNODE_LIST(dup_value)->nd_head, RNODE_LIST(value)->nd_head);
}
else {
RNODE_LIST(last_expr)->nd_head = block_append(p, RNODE_LIST(dup_value)->nd_head, RNODE_LIST(last_expr)->nd_head);
}
}
st_insert(literal_keys, (st_data_t)key, (st_data_t)hash);
last_expr = !head || nd_type_p(head, NODE_LIT) ? value : head;
last_expr = !head || (nd_type_p(head, NODE_LIT) || nd_type_p(head, NODE_INTEGER) || nd_type_p(head, NODE_FLOAT) || nd_type_p(head, NODE_RATIONAL) || nd_type_p(head, NODE_IMAGINARY)) ? value : head;
hash = next;
}
st_foreach(literal_keys, append_literal_keys, (st_data_t)&result);

View File

@ -4,6 +4,135 @@
#include "rubyparser.h"
static VALUE
compile_negative_numeric(VALUE val)
{
if (FIXNUM_P(val)) {
return LONG2FIX(-FIX2LONG(val));
}
if (SPECIAL_CONST_P(val)) {
#if USE_FLONUM
if (FLONUM_P(val)) {
return DBL2NUM(-RFLOAT_VALUE(val));
}
#endif
}
switch (OBJ_BUILTIN_TYPE(val))
{
case T_BIGNUM:
BIGNUM_NEGATE(val);
val = rb_big_norm(val);
break;
case T_RATIONAL:
RATIONAL_SET_NUM(val, compile_negative_numeric(RRATIONAL(val)->num));
break;
case T_COMPLEX:
RCOMPLEX_SET_REAL(val, compile_negative_numeric(RCOMPLEX(val)->real));
RCOMPLEX_SET_IMAG(val, compile_negative_numeric(RCOMPLEX(val)->imag));
break;
case T_FLOAT:
val = DBL2NUM(-RFLOAT_VALUE(val));
break;
default:
val = LONG2FIX(-FIX2LONG(val));
break;
}
return val;
}
static VALUE
compile_numeric_literal(char* val, int base)
{
return rb_cstr_to_inum(val, base, FALSE);
}
VALUE
rb_node_integer_literal_val(rb_node_integer_t* node)
{
VALUE val = compile_numeric_literal(node->val, node->base);
if (node->minus) {
val = compile_negative_numeric(val);
}
return val;
}
VALUE
rb_node_float_literal_val(rb_node_float_t* node)
{
double d = strtod(node->val, 0);
if (node->minus) {
d = -d;
}
VALUE val = DBL2NUM(d);
return val;
}
static VALUE
compile_rational_literal(char* node_val, int base, int seen_point)
{
VALUE lit;
char* val = strdup(node_val);
if (seen_point > 0) {
int len = (int)(strlen(val));
char *point = &val[seen_point];
size_t fraclen = len-seen_point-1;
memmove(point, point+1, fraclen+1);
lit = rb_rational_new(compile_numeric_literal(val, base), rb_int_positive_pow(10, fraclen));
} else {
lit = rb_rational_raw1(compile_numeric_literal(val, base));
}
free(val);
return lit;
}
VALUE
rb_node_rational_literal_val(rb_node_rational_t* node)
{
VALUE lit;
lit = compile_rational_literal(node->val, node->base, node->seen_point);
if (node->minus) {
lit = compile_negative_numeric(lit);
}
return lit;
}
VALUE
rb_node_imaginary_literal_val(rb_node_imaginary_t* node)
{
VALUE lit;
enum rb_numeric_type type = node->type;
switch (type) {
case integer_literal:
lit = compile_numeric_literal(node->val, node->base);
break;
case float_literal:{
double d = strtod(node->val, 0);
lit = DBL2NUM(d);
break;
}
case rational_literal:
lit = compile_rational_literal(node->val, node->base, node->seen_point);
break;
default:
rb_bug("unreachable");
}
lit = rb_complex_raw(INT2FIX(0), lit);
if (node->minus) {
lit = compile_negative_numeric(lit);
}
return lit;
}
#ifdef UNIVERSAL_PARSER
#include "internal.h"

View File

@ -109,6 +109,10 @@ enum node_type {
NODE_MATCH2,
NODE_MATCH3,
NODE_LIT,
NODE_INTEGER,
NODE_FLOAT,
NODE_RATIONAL,
NODE_IMAGINARY,
NODE_STR,
NODE_DSTR,
NODE_XSTR,
@ -628,6 +632,46 @@ typedef struct RNode_LIT {
VALUE nd_lit;
} rb_node_lit_t;
typedef struct RNode_INTEGER {
NODE node;
char* val;
int minus;
int base;
} rb_node_integer_t;
typedef struct RNode_FLOAT {
NODE node;
char* val;
int minus;
} rb_node_float_t;
typedef struct RNode_RATIONAL {
NODE node;
char* val;
int minus;
int base;
int seen_point;
} rb_node_rational_t;
enum rb_numeric_type {
integer_literal,
float_literal,
rational_literal
};
typedef struct RNode_IMAGINARY {
NODE node;
char* val;
int minus;
int base;
int seen_point;
enum rb_numeric_type type;
} rb_node_imaginary_t;
typedef struct RNode_STR {
NODE node;
@ -1020,6 +1064,10 @@ typedef struct RNode_ERROR {
#define RNODE_MATCH2(node) ((struct RNode_MATCH2 *)(node))
#define RNODE_MATCH3(node) ((struct RNode_MATCH3 *)(node))
#define RNODE_LIT(node) ((struct RNode_LIT *)(node))
#define RNODE_INTEGER(node) ((struct RNode_INTEGER *)(node))
#define RNODE_FLOAT(node) ((struct RNode_FLOAT *)(node))
#define RNODE_RATIONAL(node) ((struct RNode_RATIONAL *)(node))
#define RNODE_IMAGINARY(node) ((struct RNode_IMAGINARY *)(node))
#define RNODE_STR(node) ((struct RNode_STR *)(node))
#define RNODE_DSTR(node) ((struct RNode_DSTR *)(node))
#define RNODE_XSTR(node) ((struct RNode_XSTR *)(node))

View File

@ -589,7 +589,7 @@ class TestAst < Test::Unit::TestCase
assert_equal("foo", head)
assert_equal(:EVSTR, body.type)
body, = body.children
assert_equal(:LIT, body.type)
assert_equal(:INTEGER, body.type)
assert_equal([1], body.children)
end
@ -885,7 +885,7 @@ dummy
begin
a = 1
STR
(SCOPE@1:0-2:7 tbl: [:a] args: nil body: (LASGN@2:2-2:7 :a (LIT@2:6-2:7 1)))
(SCOPE@1:0-2:7 tbl: [:a] args: nil body: (LASGN@2:2-2:7 :a (INTEGER@2:6-2:7 1)))
EXP
end
@ -898,7 +898,8 @@ dummy
tbl: [:a]
args: nil
body:
(IF@1:0-2:7 (VCALL@1:3-1:7 :cond) (LASGN@2:2-2:7 :a (LIT@2:6-2:7 1)) nil))
(IF@1:0-2:7 (VCALL@1:3-1:7 :cond) (LASGN@2:2-2:7 :a (INTEGER@2:6-2:7 1))
nil))
EXP
assert_error_tolerant(<<~STR, <<~EXP)
@ -910,7 +911,7 @@ dummy
tbl: [:a]
args: nil
body:
(IF@1:0-3:4 (VCALL@1:3-1:7 :cond) (LASGN@2:2-2:7 :a (LIT@2:6-2:7 1))
(IF@1:0-3:4 (VCALL@1:3-1:7 :cond) (LASGN@2:2-2:7 :a (INTEGER@2:6-2:7 1))
(BEGIN@3:4-3:4 nil)))
EXP
end
@ -924,7 +925,7 @@ dummy
tbl: [:a]
args: nil
body:
(UNLESS@1:0-2:7 (VCALL@1:7-1:11 :cond) (LASGN@2:2-2:7 :a (LIT@2:6-2:7 1))
(UNLESS@1:0-2:7 (VCALL@1:7-1:11 :cond) (LASGN@2:2-2:7 :a (INTEGER@2:6-2:7 1))
nil))
EXP
@ -937,7 +938,7 @@ dummy
tbl: [:a]
args: nil
body:
(UNLESS@1:0-3:4 (VCALL@1:7-1:11 :cond) (LASGN@2:2-2:7 :a (LIT@2:6-2:7 1))
(UNLESS@1:0-3:4 (VCALL@1:7-1:11 :cond) (LASGN@2:2-2:7 :a (INTEGER@2:6-2:7 1))
(BEGIN@3:4-3:4 nil)))
EXP
end
@ -976,7 +977,7 @@ dummy
args: nil
body:
(CASE@1:0-2:6 (VCALL@1:5-1:6 :a)
(WHEN@2:0-2:6 (LIST@2:5-2:6 (LIT@2:5-2:6 1) nil) (BEGIN@2:6-2:6 nil)
(WHEN@2:0-2:6 (LIST@2:5-2:6 (INTEGER@2:5-2:6 1) nil) (BEGIN@2:6-2:6 nil)
nil)))
EXP
@ -993,7 +994,7 @@ dummy
(WHEN@2:0-2:11
(LIST@2:5-2:11
(OPCALL@2:5-2:11 (VCALL@2:5-2:6 :a) :==
(LIST@2:10-2:11 (LIT@2:10-2:11 1) nil)) nil)
(LIST@2:10-2:11 (INTEGER@2:10-2:11 1) nil)) nil)
(BEGIN@2:11-2:11 nil) nil)))
EXP
@ -1094,7 +1095,7 @@ dummy
tbl: []
args: nil
body:
(ITER@1:0-2:3 (FCALL@1:0-1:3 :m (LIST@1:2-1:3 (LIT@1:2-1:3 1) nil))
(ITER@1:0-2:3 (FCALL@1:0-1:3 :m (LIST@1:2-1:3 (INTEGER@1:2-1:3 1) nil))
(SCOPE@1:4-2:3 tbl: [] args: nil body: (VCALL@2:2-2:3 :a))))
EXP
end

View File

@ -228,7 +228,7 @@ if defined?(RubyVM)
AST = RubyVM::AbstractSyntaxTree
def test_lasgn_literal
ast = AST.parse("_=1")
expected = "(SCOPE@1:0-1:3 tbl: [:_] args: nil body: (LASGN@1:0-1:3 :_ (LIT@1:2-1:3 1)))"
expected = "(SCOPE@1:0-1:3 tbl: [:_] args: nil body: (LASGN@1:0-1:3 :_ (INTEGER@1:2-1:3 1)))"
assert_equal(expected, PP.singleline_pp(ast, ''.dup), ast)
end
end

View File

@ -226,6 +226,7 @@ struct rb_imemo_tmpbuf_struct {
#define rb_big_norm p->config->big_norm
#define rb_cstr_to_inum p->config->cstr_to_inum
#undef rb_float_new
#define rb_float_new p->config->float_new
#undef RFLOAT_VALUE
#define RFLOAT_VALUE p->config->float_value