diff options
author | S-H-GAMELINKS <gamelinks007@gmail.com> | 2024-01-05 12:03:11 +0900 |
---|---|---|
committer | Yuichiro Kaneko <spiketeika@gmail.com> | 2024-01-07 09:24:34 +0900 |
commit | 1b8d01136c3ff6c60325c7609d61e19ac42acd9f (patch) | |
tree | 99e027e7711867464c30a72d20f9e56a96e87a83 /parse.y | |
parent | 76afbda5b566148b9e73939e0ff9b8464d59806c (diff) |
Introduce Numeric Node's
Diffstat (limited to 'parse.y')
-rw-r--r-- | parse.y | 259 |
1 files changed, 187 insertions, 72 deletions
@@ -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); |