summaryrefslogtreecommitdiff
path: root/parse.y
diff options
context:
space:
mode:
authorS-H-GAMELINKS <gamelinks007@gmail.com>2024-01-05 12:03:11 +0900
committerYuichiro Kaneko <spiketeika@gmail.com>2024-01-07 09:24:34 +0900
commit1b8d01136c3ff6c60325c7609d61e19ac42acd9f (patch)
tree99e027e7711867464c30a72d20f9e56a96e87a83 /parse.y
parent76afbda5b566148b9e73939e0ff9b8464d59806c (diff)
Introduce Numeric Node's
Diffstat (limited to 'parse.y')
-rw-r--r--parse.y259
1 files changed, 187 insertions, 72 deletions
diff --git a/parse.y b/parse.y
index 7e714ccb2c..a8f094271f 100644
--- a/parse.y
+++ b/parse.y
@@ -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,27 +9002,40 @@ 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)
{
- if (suffix & NUM_SUFFIX_I) {
- v = rb_complex_raw(INT2FIX(0), v);
- type = tIMAGINARY;
+ enum rb_numeric_type numeric_type = integer_literal;
+
+ if (type == tFLOAT) {
+ numeric_type = float_literal;
}
- set_yylval_literal(v);
- 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;
+ numeric_type = rational_literal;
+ }
+ if (suffix & NUM_SUFFIX_I) {
+ type = tIMAGINARY;
}
- return set_number_literal(p, v, type, suffix);
+
+ 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;
}
#ifdef RIPPER
@@ -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);