Project

General

Profile

Feature #6242 » list.diff

shugo (Shugo Maeda), 04/01/2012 12:17 PM

View differences:

common.mk
hash.$(OBJEXT) \
inits.$(OBJEXT) \
io.$(OBJEXT) \
list.$(OBJEXT) \
marshal.$(OBJEXT) \
math.$(OBJEXT) \
node.$(OBJEXT) \
......
{$(VPATH)}internal.h
io.$(OBJEXT): {$(VPATH)}io.c $(RUBY_H_INCLUDES) {$(VPATH)}io.h \
{$(VPATH)}util.h $(ENCODING_H_INCLUDES) {$(VPATH)}dln.h {$(VPATH)}internal.h
list.$(OBJEXT): {$(VPATH)}list.c $(RUBY_H_INCLUDES) {$(VPATH)}util.h \
$(ENCODING_H_INCLUDES) {$(VPATH)}internal.h {$(VPATH)}node.h
main.$(OBJEXT): {$(VPATH)}main.c $(RUBY_H_INCLUDES) {$(VPATH)}debug.h \
{$(VPATH)}node.h
marshal.$(OBJEXT): {$(VPATH)}marshal.c $(RUBY_H_INCLUDES) {$(VPATH)}io.h \
gc.c
struct RMatch match;
struct RRational rational;
struct RComplex complex;
struct RCons cons;
} as;
#ifdef GC_DEBUG
const char *file;
......
gc_mark(objspace, obj->as.complex.imag, lev);
break;
case T_CONS:
gc_mark(objspace, obj->as.cons.car, lev);
gc_mark(objspace, obj->as.cons.cdr, lev);
break;
case T_STRUCT:
{
long len = RSTRUCT_LEN(obj);
include/ruby/ruby.h
RUBY_T_MATCH = 0x0d,
RUBY_T_COMPLEX = 0x0e,
RUBY_T_RATIONAL = 0x0f,
RUBY_T_CONS = 0x10,
RUBY_T_NIL = 0x11,
RUBY_T_TRUE = 0x12,
......
#define T_SYMBOL RUBY_T_SYMBOL
#define T_RATIONAL RUBY_T_RATIONAL
#define T_COMPLEX RUBY_T_COMPLEX
#define T_CONS RUBY_T_CONS
#define T_UNDEF RUBY_T_UNDEF
#define T_NODE RUBY_T_NODE
#define T_ZOMBIE RUBY_T_ZOMBIE
......
VALUE imag;
};
struct RCons {
struct RBasic basic;
VALUE car;
VALUE cdr;
};
struct RData {
struct RBasic basic;
void (*dmark)(void*);
......
#define RFILE(obj) (R_CAST(RFile)(obj))
#define RRATIONAL(obj) (R_CAST(RRational)(obj))
#define RCOMPLEX(obj) (R_CAST(RComplex)(obj))
#define RCONS(obj) (R_CAST(RCons)(obj))
#define FL_SINGLETON FL_USER0
#define FL_RESERVED1 (((VALUE)1)<<5)
......
RUBY_EXTERN VALUE rb_cBignum;
RUBY_EXTERN VALUE rb_cBinding;
RUBY_EXTERN VALUE rb_cClass;
RUBY_EXTERN VALUE rb_cCons;
RUBY_EXTERN VALUE rb_cCont;
RUBY_EXTERN VALUE rb_cDir;
RUBY_EXTERN VALUE rb_cData;
......
RUBY_EXTERN VALUE rb_cHash;
RUBY_EXTERN VALUE rb_cInteger;
RUBY_EXTERN VALUE rb_cIO;
RUBY_EXTERN VALUE rb_cList;
RUBY_EXTERN VALUE rb_cMatch;
RUBY_EXTERN VALUE rb_cMethod;
RUBY_EXTERN VALUE rb_cModule;
inits.c
CALL(Cont);
CALL(Rational);
CALL(Complex);
CALL(List);
CALL(version);
}
#undef CALL
list.c
/**********************************************************************
list.c -
Copyright (C) 2012 Shugo Maeda
**********************************************************************/
#include "ruby/ruby.h"
#include "ruby/util.h"
#include "ruby/encoding.h"
#include "internal.h"
#include "node.h"
VALUE rb_cCons;
static ID id_each;
static VALUE cons_new(VALUE car, VALUE cdr);
static VALUE
list_s_create(int argc, VALUE *argv, VALUE klass)
{
if (argc == 0) {
return Qnil;
}
else {
int i;
VALUE cons = cons_new(argv[argc - 1], Qnil);
for (i = argc - 2; i >= 0; i--) {
cons = cons_new(argv[i], cons);
}
return cons;
}
}
static VALUE
cons_alloc(VALUE klass)
{
NEWOBJ(ary, struct RCons);
OBJSETUP(ary, klass, T_CONS);
return (VALUE)ary;
}
static VALUE
cons_initialize(VALUE self, VALUE car, VALUE cdr)
{
RCONS(self)->car = car;
RCONS(self)->cdr = cdr;
return Qnil;
}
static VALUE
cons_new(VALUE car, VALUE cdr)
{
VALUE cons;
cons = cons_alloc(rb_cCons);
cons_initialize(cons, car, cdr);
return cons;
}
static VALUE
cons_car(VALUE self)
{
return RCONS(self)->car;
}
static VALUE
cons_cdr(VALUE self)
{
return RCONS(self)->cdr;
}
static VALUE
cons_each(VALUE self)
{
rb_yield(RCONS(self)->car);
rb_funcall_passing_block(RCONS(self)->cdr, id_each, 0, 0);
return Qnil;
}
static VALUE
cons_inspect_i(VALUE i, VALUE arg, int argc, VALUE *argv)
{
NODE *memo = RNODE(arg);
VALUE str = memo->u1.value;
long is_first = memo->u3.state;
if (is_first) {
memo->u3.state = FALSE;
}
else {
rb_str_cat2(str, ", ");
}
rb_str_concat(str, rb_inspect(i));
return Qnil;
}
static VALUE
cons_inspect(VALUE self)
{
VALUE str = rb_str_new2("S[");
NODE *memo = NEW_MEMO(str, 0, TRUE);
rb_block_call(self, rb_intern("each"), 0, 0, cons_inspect_i, (VALUE) memo);
rb_str_cat2(str, "]");
return str;
}
static VALUE
nil_each(VALUE self)
{
return Qnil;
}
static VALUE
obj_cons(VALUE car, VALUE cdr)
{
return cons_new(car, cdr);
}
void
Init_List(void)
{
rb_define_global_const("S", rb_cList);
rb_include_module(rb_cList, rb_mEnumerable);
rb_define_singleton_method(rb_cList, "[]", list_s_create, -1);
rb_cCons = rb_define_class("Cons", rb_cList);
rb_define_alloc_func(rb_cCons, cons_alloc);
rb_define_method(rb_cCons, "initialize", cons_initialize, 2);
rb_define_method(rb_cCons, "car", cons_car, 0);
rb_define_method(rb_cCons, "head", cons_car, 0);
rb_define_method(rb_cCons, "cdr", cons_cdr, 0);
rb_define_method(rb_cCons, "tail", cons_cdr, 0);
rb_define_method(rb_cCons, "each", cons_each, 0);
rb_define_method(rb_cCons, "inspect", cons_inspect, 0);
rb_define_method(rb_cNilClass, "each", nil_each, 0);
rb_define_method(rb_mKernel, ":::", obj_cons, 1);
id_each = rb_intern("each");
}
object.c
VALUE rb_cClass;
VALUE rb_cData;
VALUE rb_cList;
VALUE rb_cNilClass;
VALUE rb_cTrueClass;
VALUE rb_cFalseClass;
......
rb_define_global_function("Array", rb_f_array, 1);
rb_define_global_function("Hash", rb_f_hash, 1);
rb_cNilClass = rb_define_class("NilClass", rb_cObject);
rb_cList = rb_define_class("List", rb_cObject);
rb_cNilClass = rb_define_class("NilClass", rb_cList);
rb_define_method(rb_cNilClass, "to_i", nil_to_i, 0);
rb_define_method(rb_cNilClass, "to_f", nil_to_f, 0);
rb_define_method(rb_cNilClass, "to_s", nil_to_s, 0);
parse.y
%token tLSHFT tRSHFT /* << and >> */
%token tCOLON2 /* :: */
%token tCOLON3 /* :: at EXPR_BEG */
%token tCOLON4 /* ::: */
%token <id> tOP_ASGN /* +=, -= etc. */
%token tASSOC /* => */
%token tLPAREN /* ( */
......
%right '=' tOP_ASGN
%left modifier_rescue
%right '?' ':'
%right tCOLON4
%nonassoc tDOT2 tDOT3
%left tOROP
%left tANDOP
......
| tAREF { ifndef_ripper($$ = tAREF); }
| tASET { ifndef_ripper($$ = tASET); }
| '`' { ifndef_ripper($$ = '`'); }
| tCOLON4 { ifndef_ripper($$ = tCOLON4); }
;
reswords : keyword__LINE__ | keyword__FILE__ | keyword__ENCODING__
......
$$ = dispatch1(assign_error, $$);
%*/
}
| arg tCOLON4 arg
{
/*%%%*/
$$ = call_bin_op($1, tCOLON4, $3);
/*%
$$ = dispatch3(binary, $1, ID2SYM(tCOLON4), $3);
%*/
}
| arg tDOT2 arg
{
/*%%%*/
......
case ':':
c = nextc();
if (c == ':') {
c = nextc();
if (c == ':') {
return tCOLON4;
}
pushback(c);
if (IS_BEG() || lex_state == EXPR_CLASS || IS_SPCARG(-1)) {
lex_state = EXPR_BEG;
return tCOLON3;
......
{tLSHFT, "<<"},
{tRSHFT, ">>"},
{tCOLON2, "::"},
{tCOLON4, ":::"},
};
#define op_tbl_count numberof(op_tbl)
template/id.h.tmpl
vpath.find do |dir|
begin
if line = File.read(File.join(dir, input))[/^\s*enum\s+yytokentype\s*\{([^{}]*)\s*\};/m, 1]
tokens = line.scan(/\b(t(?:LAST_TOKEN|U(?:PLUS|MINUS)|POW|CMP|EQQ?|[NGL]EQ|(?:AND|OR)OP|N?MATCH|DOT\d|AREF|ASET|[LR]SHFT|LAMBDA)|id\w+)\s*=\s*(\d+),?/m)
tokens = line.scan(/\b(t(?:LAST_TOKEN|U(?:PLUS|MINUS)|POW|CMP|EQQ?|[NGL]EQ|(?:AND|OR)OP|N?MATCH|DOT\d|AREF|ASET|[LR]SHFT|COLON4|LAMBDA)|id\w+)\s*=\s*(\d+),?/m)
end
rescue Errno::ENOENT
nil
......
idNeqTilde = tNMATCH,
idAREF = tAREF,
idASET = tASET,
idColon4 = tCOLON4,
idLAST_TOKEN = tLAST_TOKEN >> ID_SCOPE_SHIFT,
% method_ids.each do |token|
t<%=token%>,
(1-1/6)