Skip to content

WIP: Switch to markdown and fix code blocks #49

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
Prev Previous commit
Next Next commit
lang formatting
  • Loading branch information
BuonOmo committed Apr 18, 2021
commit 5a8beef6fc03452ffb6b1907ab6f28150869726b
59 changes: 30 additions & 29 deletions load.md
Original file line number Diff line number Diff line change
@@ -15,7 +15,7 @@ Outline
At the Ruby level, there are two procedures that can be used for
loading: `require` and `load`.

```TODO-lang
```ruby
require 'uri' # load the uri library
load '/home/foo/.myrc' # read a resource file
```
@@ -41,7 +41,7 @@ Ruby's load path is in the global variable `$:`, which contains an
array of strings. For example, displaying the content of the `$:` in
the environment I usually use would show:

```TODO-lang
```
% ruby -e 'puts $:'
/usr/lib/ruby/site_ruby/1.7
/usr/lib/ruby/site_ruby/1.7/i686-linux
@@ -62,7 +62,7 @@ In a Windows environment, there will also be a drive letter.
Then, let's try to `require` the standard library `nkf.so` from the
load path.

```TODO-lang
```ruby
require 'nkf'
```

@@ -75,7 +75,7 @@ extension libraries, for example `.dll` in a Windows environment or
Let's do a simulation on my environment. `ruby` checks the following
paths in sequential order.

```TODO-lang
```
/usr/lib/ruby/site_ruby/1.7/nkf.rb
/usr/lib/ruby/site_ruby/1.7/nkf.so
/usr/lib/ruby/site_ruby/1.7/i686-linux/nkf.rb
@@ -95,7 +95,7 @@ global variable `$"`. In our case the string `"nkf.so"` has been put
there. Even if the extension has been omitted when calling `require`,
the file name in `$"` has the extension.

```TODO-lang
```ruby
require 'nkf' # after loading nkf...
p $" # ["nkf.so"] the file is locked

@@ -123,7 +123,7 @@ file in `$:`. But it can only load Ruby programs. Furthermore, the
extension cannot be omitted: the complete file name must always be
given.

```TODO-lang
```ruby
load 'uri.rb' # load the URI library that is part of the standard library
```

@@ -147,7 +147,7 @@ programs are basically evaluated at the top-level. It means the
defined constants will be top-level constants and the defined methods
will be function-style methods.

```TODO-lang
```ruby
### mylib.rb
MY_OBJECT = Object.new
def my_p(obj)
@@ -171,7 +171,7 @@ the `module` statement, it does not serve any purpose, as everything
that is at the top-level of the loaded file is put at the Ruby
top-level.

```TODO-lang
```ruby
require 'mylib' # whatever the place you require from, be it at the top-level
module SandBox
require 'mylib' # or in a module, the result is the same
@@ -213,7 +213,7 @@ bothersome so we will limit ourselves to the case when no file
extension is given.

`rb_f_require()` (simplified version)
```TODO-lang
```c
5527 VALUE
5528 rb_f_require(obj, fname)
5529 VALUE obj, fname;
@@ -272,9 +272,10 @@ actually like subroutines, and the two variables `feature` and `fname`
are more or less their parameters. These variables have the following
meaning.
|_. variable|_. meaning|_. example|
|`feature`|the library file name that will be put in `$"`|`uri.rb``nkf.so`|
|`fname`|the full path to the library|`/usr/lib/ruby/1.7/uri.rb`|
| variable | meaning | example |
| --------- | ---------------------------------------------- | -------------------------- |
| `feature` | the library file name that will be put in `$"` | `uri.rb`、`nkf.so` |
| `fname` | the full path to the library | `/usr/lib/ruby/1.7/uri.rb` |
The name `feature` can be found in the function `rb_feature_p()`. This
function checks if a file has been locked (we will look at it just
@@ -297,7 +298,7 @@ searches the file `path` in the global load path `$'`
only look at the main part.
▼ `rb_find_file()` (simplified version)
```TODO-lang
```c
2494 VALUE
2495 rb_find_file(path)
2496 VALUE path;
@@ -339,7 +340,7 @@ only look at the main part.

If we write what happens in Ruby we get the following:

```TODO-lang
```ruby
tmp = [] # make an array
$:.each do |path| # repeat on each element of the load path
tmp.push path if path.length > 0 # check the path and push it
@@ -374,7 +375,7 @@ code. Or more accurately, it is "up to just before the load". The code
of `rb_f_require()`'s `load_rb` has been put below.

`rb_f_require():load_rb`
```TODO-lang
```c
5625 load_rb:
5626 if (rb_feature_p(RSTRING(feature)->ptr, Qtrue))
5627 return Qfalse;
@@ -405,7 +406,7 @@ from one thread, and if during the loading another thread tries to load the
same file, that thread will wait for the first loading to be finished.
If it were not the case:
```TODO-lang
```ruby
Thread.fork {
require 'foo' # At the beginning of require, foo.rb is added to $"
} # However the thread changes during the evaluation of foo.rb
@@ -429,7 +430,7 @@ thread. That makes an exclusive lock. And in `rb_feature_p()`, we
wait for the loading thread to end like the following.

`rb_feature_p()` (second half)
```TODO-lang
```c
5477 rb_thread_t th;
5478
5479 while (st_lookup(loading_tbl, f, &th)) {
@@ -463,7 +464,7 @@ We will now look at the loading process itself. Let's start by the
part inside `rb_f_require()`'s `load_rb` loading Ruby programs.
▼ `rb_f_require()-load_rb-` loading
```TODO-lang
```c
5638 PUSH_TAG(PROT_NONE);
5639 if ((state = EXEC_TAG()) == 0) {
5640 rb_load(fname, 0);
@@ -483,7 +484,7 @@ And the second argument `wrap` is folded with 0
because it is 0 in the above calling code.

`rb_load()` (simplified edition)
```TODO-lang
```c
void
rb_load(fname, /* wrap=0 */)
VALUE fname;
@@ -584,7 +585,7 @@ all of them would be put in `eval.c` in the first place.
Then, it is `rb_load_file()`.
▼ `rb_load_file()`
```TODO-lang
```c
865 void
866 rb_load_file(fname)
867 char *fname;
@@ -605,7 +606,7 @@ non essential things have already been removed.

<p class="caption">▼ `load_file()` (simplified edition)</p>

```TODO-lang
```c
static void
load_file(fname, /* script=0 */)
char *fname;
@@ -645,7 +646,7 @@ result.
That's all for the loading code. Finally, the calls were quite deep so
the callgraph of `rb_f_require()` is shown bellow.
```TODO-lang
```
rb_f_require ....eval.c
rb_find_file ....file.c
dln_find_file ....dln.c
@@ -679,7 +680,7 @@ If you're using Windows, probably your IDE will have a tracer built in. Well, as
The output is done on `stderr` so it was redirected using `2>&1`.
```TODO-lang
```
% strace ruby -e 'require "rational"' 2>&1 | grep '^open'
open("/etc/ld.so.preload", O_RDONLY) = -1 ENOENT
open("/etc/ld.so.cache", O_RDONLY) = 3
@@ -707,7 +708,7 @@ start with `rb_f_require()`'s `load_dyna`. However, we do not need the
part about locking anymore so it was removed.
▼ `rb_f_require()`-`load_dyna`
```TODO-lang
```c
5607 {
5608 int volatile old_vmode = scope_vmode;
5609
@@ -745,7 +746,7 @@ Since I'm using `gcc` on Linux, I can create a runnable program in the following
manner.


```TODO-lang
```
% gcc hello.c
```

@@ -754,7 +755,7 @@ According to the file name, this is probably an "Hello, World!" program.
In UNIX, `gcc` outputs a program into a file named `a.out` by default,
so you can subsequently execute it in the following way:

```TODO-lang
```
% ./a.out
Hello, World!
```
@@ -928,7 +929,7 @@ but its structure is simple because of some reasons.
Take a look at the outline first.

`dln_load()` (outline)
```TODO-lang
```c
void*
dln_load(file)
const char *file;
@@ -969,7 +970,7 @@ Supported APIs are as follows:
First, let's start with the API code for the `dlopen` series.
▼ `dln_load()`-`dlopen()`
```TODO-lang
```c
1254 void*
1255 dln_load(file)
1256 const char *file;
@@ -1049,7 +1050,7 @@ As for Win32, `LoadLibrary()` and `GetProcAddress()` are used.
It is very general Win32 API which also appears on MSDN.

`dln_load()`-Win32
```TODO-lang
```c
1254 void*
1255 dln_load(file)
1256 const char *file;
46 changes: 23 additions & 23 deletions method.md
Original file line number Diff line number Diff line change
@@ -22,7 +22,7 @@ confusing, let's strictly define terms here:



```TODO-lang
```ruby
m(a) # a is a "normal argument"
m(*list) # list is an "array argument"
m(&block) # block is a "block argument"
@@ -49,14 +49,14 @@ parameters" will be discussed in the next chapter.
<p class="caption">▼The Source Program</p>
```TODO-lang
```ruby
obj.method(7,8)
```
<p class="caption">▼Its Syntax Tree</p>
```TODO-lang
```
NODE_CALL
nd_mid = 9049 (method)
nd_recv:
@@ -92,7 +92,7 @@ Now, let's look at the handler of `NODE_CALL` in `rb_eval()`.
<p class="caption">▼ `rb_eval()``NODE_CALL` </p>
```TODO-lang
```c
2745 case NODE_CALL:
2746 {
2747 VALUE recv;
@@ -136,7 +136,7 @@ Therefore, something like the following is a boilerplate:
```TODO-lang
```c
int argc; VALUE *argv; /* used in SETUP_ARGS */
TMP_PROTECT;
@@ -152,7 +152,7 @@ Let's look at it:
<p class="caption">▼ `SETUP_ARGS()` </p>

```TODO-lang
```c
1780 #define SETUP_ARGS(anode) do {\
1781 NODE *n = anode;\
1782 if (!n) {\ no arguments
@@ -207,7 +207,7 @@ If I write in the code (and tidy up a little), it becomes as follows.
```TODO-lang
```c
/***** else if clause、argc!=0 *****/
int i;
n = anode;
@@ -266,7 +266,7 @@ of them.
<p class="caption">▼ `rb_call()` (simplified)</p>
```TODO-lang
```c
static VALUE
rb_call(klass, recv, mid, argc, argv, scope)
VALUE klass, recv;
@@ -319,7 +319,7 @@ What is looking up the cache is the first half of `rb_call()`. Only with



```TODO-lang
```c
ent = cache + EXPR1(klass, mid);
```

@@ -349,7 +349,7 @@ Next, let's examine the structure of the method cache in detail.

<p class="caption">Method Cache</p>

```TODO-lang
```c
180 #define CACHE_SIZE 0x800
181 #define CACHE_MASK 0x7ff
182 #define EXPR1(c,m) ((((c)>>3)^(m))&CACHE_MASK)
@@ -431,7 +431,7 @@ look at it by dividing into small portions. Starting with the outline:
<p class="caption">▼ `rb_call0()` (Outline)</p>
```TODO-lang
```c
4482 static VALUE
4483 rb_call0(klass, recv, id, oid, argc, argv, body, nosuper)
4484 VALUE klass, recv;
@@ -521,7 +521,7 @@ could be ignored. The important things are only `NODE_CFUNC`, `NODE_SCOPE` and
<p class="caption">▼ `PUSH_FRAME() POP_FRAME()` </p>
```TODO-lang
```c
536 #define PUSH_FRAME() do { \
537 struct FRAME _frame; \
538 _frame.prev = ruby_frame; \
@@ -564,7 +564,7 @@ following line:

<p class="caption">`rb_call0()``NODE_CFUNC` (simplified)</p>

```TODO-lang
```c
case NODE_CFUNC:
result = call_cfunc(body->nd_cfnc, recv, len, argc, argv);
break;
@@ -576,7 +576,7 @@ Then, as for `call_cfunc()` ...

<p class="caption">`call_cfunc()` (simplified)</p>

```TODO-lang
```c
4394 static VALUE
4395 call_cfunc(func, recv, len, argc, argv)
4396 VALUE (*func)();
@@ -639,7 +639,7 @@ This part forms the foundation of Ruby.
<p class="caption">▼ `rb_call0()` − `NODE_SCOPE` (outline)</p>
```TODO-lang
```c
4568 case NODE_SCOPE:
4569 {
4570 int state;
@@ -747,7 +747,7 @@ But before that, I'd like you to first check the syntax tree of the method again
```TODO-lang
```
% ruby -rnodedump -e 'def m(a) nil end'
NODE_SCOPE
nd_rval = (null)
@@ -793,7 +793,7 @@ For example, if you write a definition as below,
```TODO-lang
```ruby
def m(a, b, c = nil, *rest)
lvar1 = nil
end
@@ -804,7 +804,7 @@ local variable IDs are assigned as follows.
```TODO-lang
```
0 1 2 3 4 5 6
$_ $~ a b c rest lvar1
```
@@ -816,7 +816,7 @@ Taking this into considerations, let's look at the code.

<p class="caption">`rb_call0()``NODE_SCOPE` −assignments of arguments</p>

```TODO-lang
```c
4601 if (nd_type(body) == NODE_ARGS) { /* no body */
4602 node = body; /* NODE_ARGS */
4603 body = 0; /* the method body */
@@ -904,7 +904,7 @@ It means the following form:
```TODO-lang
```ruby
super
```
@@ -919,7 +919,7 @@ If there's not, the one after option parameters are assigned seems better.
```TODO-lang
```ruby
def m(a, b, *rest)
super # probably 5, 6, 7, 8 should be passed
end
@@ -956,7 +956,7 @@ and `NODE_ZSUPER` is `super` without arguments.
<p class="caption">▼ `rb_eval()` − `NODE_SUPER` </p>
```TODO-lang
```c
2780 case NODE_SUPER:
2781 case NODE_ZSUPER:
2782 {
@@ -1044,7 +1044,7 @@ What happens if `String.new` is replaced by new definition and `super` is called
```TODO-lang
```ruby
def String.new
super
end
184 changes: 93 additions & 91 deletions minimum.md

Large diffs are not rendered by default.

92 changes: 46 additions & 46 deletions module.md

Large diffs are not rendered by default.

52 changes: 27 additions & 25 deletions name.md
Original file line number Diff line number Diff line change
@@ -24,7 +24,7 @@ However, data structures other than hash tables can, of course, record
one-to-one relations. For example, a list of the following structs will suffice
for this purpose.

```TODO-lang
```c
struct entry {
ID key;
VALUE val;
@@ -44,7 +44,7 @@ created by Matsumoto, rather:

`st.c` credits

```TODO-lang
```c
1 /* This is a public domain general purpose hash table package
written by Peter Moore @ UCB. */

@@ -125,7 +125,7 @@ The following is the data type of `st_table`.

`st_table`

```TODO-lang
```c
9 typedef struct st_table st_table;

16 struct st_table {
@@ -140,7 +140,7 @@ The following is the data type of `st_table`.
▼ `struct st_table_entry`
```TODO-lang
```c
16 struct st_table_entry {
17 unsigned int hash;
18 char *key;
@@ -167,7 +167,7 @@ So, let us comment on `st_hash_type`.

`struct st_hash_type`

```TODO-lang
```c
11 struct st_hash_type {
12 int (*compare)(); /* comparison function */
13 int (*hash)(); /* hash function */
@@ -178,15 +178,15 @@ So, let us comment on `st_hash_type`.
This is still Chapter 3 so let us examine it attentively.
```TODO-lang
```c
int (*compare)()
```

This part shows, of course, the member `compare` which has a data type of
"a pointer to a function that returns an `int`". `hash` is also of the same type.
This variable is substituted in the following way:

```TODO-lang
```c
int
great_function(int n)
{
@@ -201,7 +201,7 @@ great_function(int n)
And it is called like this:
```TODO-lang
```c
(*f)(7);
}
```
@@ -244,7 +244,7 @@ integer data type keys.

`st_init_numtable()`

```TODO-lang
```c
182 st_table*
183 st_init_numtable()
184 {
@@ -260,7 +260,7 @@ Regarding this `type_numhash`:
▼ `type_numhash`
```TODO-lang
```c
37 static struct st_hash_type type_numhash = {
38 numcmp,
39 numhash,
@@ -294,7 +294,7 @@ function that searches the hash table, `st_lookup()`.

`st_lookup()`

```TODO-lang
```c
247 int
248 st_lookup(table, key, value)
249 st_table *table;
@@ -324,15 +324,15 @@ look at them in order.
▼ `do_hash()`
```TODO-lang
```c
68 #define do_hash(key,table) (unsigned int)(*(table)->type->hash)((key))
(st.c)
```

Just in case, let us write down the macro body that is difficult to understand:

```TODO-lang
```c
(table)->type->hash
```

@@ -345,7 +345,7 @@ Next, let us examine `FIND_ENTRY()`.

`FIND_ENTRY()`

```TODO-lang
```c
235 #define FIND_ENTRY(table, ptr, hash_val, bin_pos) do {\
236 bin_pos = hash_val%(table)->num_bins;\
237 ptr = (table)->bins[bin_pos];\
@@ -386,7 +386,7 @@ end.
Also, there is no semicolon added after the `while(0)`.
```TODO-lang
```c
FIND_ENTRY();
```

@@ -402,7 +402,7 @@ in the function name.

`st_add_direct()`

```TODO-lang
```c
308 void
309 st_add_direct(table, key, value)
310 st_table *table;
@@ -428,7 +428,7 @@ Since the name is all uppercase, we can anticipate that is a macro.
▼ `ADD_DIRECT()`
```TODO-lang
```c
268 #define ADD_DIRECT(table, key, value, hash_val, bin_pos) \
269 do { \
270 st_table_entry *entry; \
@@ -460,7 +460,7 @@ The first `if` is an exception case so I will explain it afterwards.
(B) Insert the `entry` into the start of the list.
This is the idiom for handling the list. In other words,

```TODO-lang
```c
entry->next = list_beg;
list_beg = entry;
```
@@ -473,7 +473,7 @@ Now, let me explain the code I left aside.

`ADD_DIRECT()`-`rehash`

```TODO-lang
```c
271 if (table->num_entries / (table->num_bins) \
> ST_DEFAULT_MAX_DENSITY) { \
272 rehash(table); \
@@ -493,7 +493,7 @@ The current `ST_DEFAULT_MAX_DENSITY` is
▼ `ST_DEFAULT_MAX_DENSITY`
```TODO-lang
```c
23 #define ST_DEFAULT_MAX_DENSITY 5
(st.c)
@@ -509,7 +509,7 @@ then the size will be increased.

`st_insert()`

```TODO-lang
```c
286 int
287 st_insert(table, key, value)
288 register st_table *table;
@@ -553,7 +553,9 @@ is rather long, so let's omit the middle.
▼ `rb_intern()` (simplified)
```TODO-lang
<!-- TODO: is it yacc? -->
```yacc
5451 static st_table *sym_tbl; /* char* to ID */
5452 static st_table *sym_rev_tbl; /* ID to char* */
@@ -604,7 +606,7 @@ simplify it.

`rb_id2name()` (simplified)

```TODO-lang
```c
char *
rb_id2name(id)
ID id;
@@ -639,7 +641,7 @@ And it can be obtained like so: `"string".intern`. The implementation of
▼ `rb_str_intern()`
```TODO-lang
```c
2996 static VALUE
2997 rb_str_intern(str)
2998 VALUE str;
@@ -671,7 +673,7 @@ The implementation is in `sym_to_s`.

`sym_to_s()`

```TODO-lang
```c
522 static VALUE
523 sym_to_s(sym)
524 VALUE sym;
96 changes: 48 additions & 48 deletions object.md
Original file line number Diff line number Diff line change
@@ -44,7 +44,7 @@ Here is the definition of `VALUE`:

`VALUE`

```TODO-lang
```c
71 typedef unsigned long VALUE;

(ruby.h)
@@ -60,19 +60,19 @@ but some time ago it seems there were quite a few of them.
The structs, on the other hand, have several variations,
a different struct is used based on the class of the object.

| `struct RObject` | all things for which none of the following
applies |
| `struct RClass` | class object |
| `struct RFloat` | small numbers |
| `struct RString` | string |
| `struct RArray` | array |
| `struct RRegexp` | regular expression |
| `struct RHash` | hash table |
| `struct RFile` | `IO`, `File`, `Socket`, etc... |
| `struct RData` | all the classes defined at C level, except the
ones mentioned above |
| `struct RStruct` | Ruby's `Struct` class |
| `struct RBignum` | big integers |
| `struct` | variation |
| ---------------- | ------------------------------------------------------------------- |
| `struct RObject` | all things for which none of the following applies |
| `struct RClass` | class object |
| `struct RFloat` | small numbers |
| `struct RString` | string |
| `struct RArray` | array |
| `struct RRegexp` | regular expression |
| `struct RHash` | hash table |
| `struct RFile` | `IO`, `File`, `Socket`, etc... |
| `struct RData` | all the classes defined at C level, except the ones mentioned above |
| `struct RStruct` | Ruby's `Struct` class |
| `struct RBignum` | big integers |

For example, for an string object, `struct RString` is used, so we will have
something like the following.
@@ -86,7 +86,7 @@ Let's look at the definition of a few object structs.

▼ Examples of object struct

```TODO-lang
```c
/* struct for ordinary objects */
295 struct RObject {
296 struct RBasic basic;
@@ -127,7 +127,7 @@ That's why `Rxxxx()` macros have been made for each object
struct. For example, for `struct RString` there is `RSTRING()`, for
`struct RArray` there is `RARRAY()`, etc... These macros are used like this:
```TODO-lang
```c
VALUE str = ....;
VALUE arr = ....;
@@ -152,7 +152,7 @@ for `struct RBasic`:

`struct RBasic`

```TODO-lang
```c
290 struct RBasic {
291 unsigned long flags;
292 VALUE klass;
@@ -165,7 +165,7 @@ for `struct RBasic`:
(for instance `struct RObject`). The type flags are named `T_xxxx`, and can be
obtained from a `VALUE` using the macro `TYPE()`. Here is an example:
```TODO-lang
```c
VALUE str;
str = rb_str_new(); /* creates a Ruby string (its struct is RString) */
TYPE(str); /* the return value is T_STRING */
@@ -273,7 +273,7 @@ to a `Fixnum`, and confirm that `Fixnum` are directly embedded in `VALUE`.

`INT2FIX`

```TODO-lang
```c
123 #define INT2FIX(i) ((VALUE)(((long)(i))<<1 | FIXNUM_FLAG))
122 #define FIXNUM_FLAG 0x01

@@ -308,7 +308,7 @@ In the first place, there's a type named `ID` used inside `ruby`. Here it is.
▼ `ID`
```TODO-lang
```c
72 typedef unsigned long ID;
(ruby.h)
@@ -342,7 +342,7 @@ why `Symbol`, like `Fixnum`, was made embedded in `VALUE`. Let's look at the

`ID2SYM`

```TODO-lang
```c
158 #define SYMBOL_FLAG 0x0e
160 #define ID2SYM(x) ((VALUE)(((long)(x))<<8|SYMBOL_FLAG))

@@ -359,7 +359,7 @@ Finally, let's see the reverse conversion of `ID2SYM()`, `SYM2ID()`.
▼ `SYM2ID()`
```TODO-lang
```c
161 #define SYM2ID(x) RSHIFT((long)x,8)
(ruby.h)
@@ -376,7 +376,7 @@ values at the C level are defined like this:

`true false nil`

```TODO-lang
```c
164 #define Qfalse 0 /* Ruby's false */
165 #define Qtrue 2 /* Ruby's true */
166 #define Qnil 4 /* Ruby's nil */
@@ -397,7 +397,7 @@ For `Qnil`, there is a macro dedicated to check if a `VALUE` is `Qnil` or not,

`NIL_P()`

```TODO-lang
```c
170 #define NIL_P(v) ((VALUE)(v) == Qnil)

(ruby.h)
@@ -415,7 +415,7 @@ That's why there's the `RTEST()` macro to do Ruby-style test in C.
▼ `RTEST()`
```TODO-lang
```c
169 #define RTEST(v) (((VALUE)(v) & ~Qnil) != 0)
(ruby.h)
@@ -436,7 +436,7 @@ not have the fun answer I was expecting...

`Qundef`

```TODO-lang
```c
167 #define Qundef 6 /* undefined value for placeholder */

(ruby.h)
@@ -465,7 +465,7 @@ differentiated by the `T_MODULE` struct flag.

`struct RClass`

```TODO-lang
```c
300 struct RClass {
301 struct RBasic basic;
302 struct st_table *iv_tbl;
@@ -518,7 +518,7 @@ The sequential search process in `m_tbl` is done by `search_method()`.
▼ `search_method()`
```TODO-lang
```c
256 static NODE*
257 search_method(klass, id, origin)
258 VALUE klass, *origin;
@@ -543,7 +543,7 @@ This function searches the method named `id` in the class object `klass`.

`RCLASS(value)` is the macro doing:

```TODO-lang
```c
((struct RClass*)(value))
```

@@ -572,7 +572,7 @@ but is it really so? Let's look at the function

`rb_ivar_set()`

```TODO-lang
```c
/* assign val to the id instance variable of obj */
984 VALUE
985 rb_ivar_set(obj, id, val)
@@ -610,7 +610,7 @@ Therefore, we should wholly ignore them at first read.
After removing the error handling, only the `switch` remains, but
```TODO-lang
```c
switch (TYPE(obj)) {
case T_aaaa:
case T_bbbb:
@@ -631,7 +631,7 @@ the basis that their second member is `iv_tbl`. Let's confirm it in practice.

▼ Structs whose second member is `iv_tbl`

```TODO-lang
```c
/* TYPE(val) == T_OBJECT */
295 struct RObject {
296 struct RBasic basic;
@@ -655,7 +655,7 @@ It records the correspondences between the instance variable names and their val
In `rb_ivar_set()`, let's look again the code for the structs having
`iv_tbl`.
```TODO-lang
```c
if (!ROBJECT(obj)->iv_tbl)
ROBJECT(obj)->iv_tbl = st_init_numtable();
st_insert(ROBJECT(obj)->iv_tbl, id, val);
@@ -678,7 +678,7 @@ its instance variable table is for the class object itself.
In Ruby programs, it corresponds to
something like the following:

```TODO-lang
```ruby
class C
@ivar = "content"
end
@@ -691,7 +691,7 @@ an object whose struct is not one of `T_OBJECT T_MODULE T_CLASS`?

`rb_ivar_set()` in the case there is no `iv_tbl`

```TODO-lang
```c
1000 default:
1001 generic_ivar_set(obj, id, val);
1002 break;
@@ -719,7 +719,7 @@ Let's see this in practice.
▼ `generic_ivar_set()`
```TODO-lang
```c
801 static st_table *generic_iv_tbl;
830 static void
@@ -840,7 +840,7 @@ how to get them.

`rb_ivar_get()`

```TODO-lang
```c
960 VALUE
961 rb_ivar_get(obj, id)
962 VALUE obj;
@@ -911,7 +911,7 @@ its subclasses.
▼ `struct RString`
```TODO-lang
```c
314 struct RString {
315 struct RBasic basic;
316 long len;
@@ -956,7 +956,7 @@ characteristics.
Ruby's strings can be modified (are mutable). By mutable I mean after the
following code:

```TODO-lang
```ruby
s = "str" # create a string and assign it to s
s.concat("ing") # append "ing" to this string object
p(s) # show "string"
@@ -980,7 +980,7 @@ additional memory.
So what is this other `aux.shared`? It's to speed up the creation of literal
strings. Have a look at the following Ruby program.

```TODO-lang
```ruby
while true do # repeat indefinitely
a = "str" # create a string with "str" as content and assign it to a
a.concat("ing") # append "ing" to the object pointed by a
@@ -1014,7 +1014,7 @@ modifying strings created as litterals, `aux.shared` has to be separated.
Before ending this section, I'll write some examples of dealing with `RString`.
I'd like you to regard `str` as a `VALUE` that points to `RString` when reading this.

```TODO-lang
```c
RSTRING(str)->len; /* length */
RSTRING(str)->ptr[0]; /* first character */
str = rb_str_new("content", 7); /* create a string with "content" as its content
@@ -1031,7 +1031,7 @@ rb_str_cat2(str, "end"); /* Concatenate a C string to a Ruby string */
▼ `struct RArray`
```TODO-lang
```c
324 struct RArray {
325 struct RBasic basic;
326 long len;
@@ -1063,7 +1063,7 @@ With `RARRAY(arr)->ptr` and `RARRAY(arr)->len`, you can refer to the members,
and it is allowed, but you must not assign to them,
etc. We'll only look at simple examples:

```TODO-lang
```c
/* manage an array from C */
VALUE ary;
ary = rb_ary_new(); /* create an empty array */
@@ -1084,7 +1084,7 @@ It's the struct for the instances of the regular expression class `Regexp`.
▼ `struct RRegexp`
```TODO-lang
```c
334 struct RRegexp {
335 struct RBasic basic;
336 struct re_pattern_buffer *ptr;
@@ -1110,7 +1110,7 @@ which is Ruby's hash table.

`struct RHash`

```TODO-lang
```c
341 struct RHash {
342 struct RBasic basic;
343 struct st_table *tbl;
@@ -1134,7 +1134,7 @@ its subclasses.
▼ `struct RFile`
```TODO-lang
```c
348 struct RFile {
349 struct RBasic basic;
350 struct OpenFile *fptr;
@@ -1145,7 +1145,7 @@ its subclasses.

`OpenFile`

```TODO-lang
```c
19 typedef struct OpenFile {
20 FILE *f; /* stdio ptr for read/write */
21 FILE *f2; /* additional ptr for rw pipes */
@@ -1176,7 +1176,7 @@ for managing a pointer to a user defined struct" has been created on
▼ `struct RData`
```TODO-lang
```c
353 struct RData {
354 struct RBasic basic;
355 void (*dmark) _((void*));
97 changes: 49 additions & 48 deletions parser.md
Original file line number Diff line number Diff line change
@@ -712,7 +712,7 @@ is to deal with the methods without parentheses.
For example, it is to distinguish the next two from each other:


```TODO-lang
```ruby
p Net::HTTP # p(Net::HTTP)
p Net ::HTTP # p(Net(::HTTP))
```
@@ -791,7 +791,7 @@ surrounding the multiple arguments of a `return` with parentheses
as in the following code should be impossible.


```TODO-lang
```ruby
return(1, 2, 3) # interpreted as return (1,2,3) and results in parse error
```

@@ -840,7 +840,7 @@ Because `primary` is also `arg`,
we can also do something like this.


```TODO-lang
```ruby
p(if true then 'ok' end) # shows "ok"
```

@@ -1096,7 +1096,7 @@ First, I'll start with `nextc()` that seems the most orthodox.

<p class="caption">▼ `nextc()` </p>

```TODO-lang
```yacc
2468 static inline int
2469 nextc()
2470 {
@@ -1193,7 +1193,7 @@ I searched the place where setting `lex_gets` and this is what I found:

<p class="caption">▼ set `lex_gets` </p>

```TODO-lang
```yacc
2430 NODE*
2431 rb_compile_string(f, s, line)
2432 const char *f;
@@ -1228,7 +1228,7 @@ On the other hand, `lex_get_str()` is defined as follows:

<p class="caption">▼ `lex_get_str()` </p>

```TODO-lang
```yacc
2398 static int lex_gets_ptr;
2400 static VALUE
@@ -1279,7 +1279,7 @@ we can understand the rest easily.

<p class="caption">▼ `pushback()` </p>

```TODO-lang
```yacc
2501 static void
2502 pushback(c)
2503 int c;
@@ -1300,7 +1300,7 @@ we can understand the rest easily.

<p class="caption">▼ `peek()` </p>

```TODO-lang
```yacc
2509 #define peek(c) (lex_p != lex_pend && (c) == *lex_p)
(parse.y)
@@ -1329,7 +1329,7 @@ Now, we'll start with the data structures.

<p class="caption">▼ The Token Buffer </p>

```TODO-lang
```yacc
2271 static char *tokenbuf = NULL;
2272 static int tokidx, toksiz = 0;
@@ -1356,7 +1356,7 @@ read `newtok()`, which starts a new token.

<p class="caption">▼ `newtok()` </p>

```TODO-lang
```yacc
2516 static char*
2517 newtok()
2518 {
@@ -1394,7 +1394,7 @@ Next, let's look at the `tokadd()` to add a character to token buffer.

<p class="caption">▼ `tokadd()` </p>

```TODO-lang
```yacc
2531 static void
2532 tokadd(c)
2533 char c;
@@ -1421,7 +1421,7 @@ The rest interfaces are summarized below.

<p class="caption">▼ `tokfix() tok() toklen() toklast()` </p>

```TODO-lang
```yacc
2511 #define tokfix() (tokenbuf[tokidx]='\0')
2512 #define tok() tokenbuf
2513 #define toklen() tokidx
@@ -1446,7 +1446,7 @@ First, I'll show the whole structure that some parts of it are left out.

<p class="caption">▼ `yylex` outline </p>

```TODO-lang
```yacc
3106 static int
3107 yylex()
3108 {
@@ -1534,7 +1534,7 @@ Let's start with what is simple first.

<p class="caption">▼ `yylex` - `'!'` </p>

```TODO-lang
```yacc
3205 case '!':
3206 lex_state = EXPR_BEG;
3207 if ((c = nextc()) == '=') {
@@ -1550,11 +1550,11 @@ Let's start with what is simple first.
```


I wroute out the meaning of the code,
I wrote out the meaning of the code,
so I'd like you to read them by comparing each other.


```TODO-lang
```
case '!':
move to EXPR_BEG
if (the next character is '=' then) {
@@ -1595,7 +1595,7 @@ Next, we'll try to look at `'<'` as an example of using `yylval` (the value of a

<p class="caption">▼ `yylex`−`'&gt;'`</p>

```TODO-lang
```yacc
3296 case '>':
3297 switch (lex_state) {
3298 case EXPR_FNAME: case EXPR_DOT:
@@ -1657,7 +1657,7 @@ The code of `':'` shown below is an example that a space changes the behavior.

<p class="caption">▼ `yylex`−`':'`</p>

```TODO-lang
```yacc
3761 case ':':
3762 c = nextc();
3763 if (c == ':') {
@@ -1705,7 +1705,7 @@ It is the scanning pattern of identifiers.

First, the outline of `yylex` was as follows:

```TODO-lang
```yacc
yylex(...)
{
switch (c = nextc()) {
@@ -1727,7 +1727,7 @@ This is relatively long, so I'll show it with comments.

<p class="caption">▼ `yylex` -- identifiers </p>

```TODO-lang
```yacc
4081 case '@': /* an instance variable or a class variable */
4082 c = nextc();
4083 newtok();
@@ -1791,7 +1791,7 @@ at the place where adding `!` or `?`.
This part is to interpret in the next way.


```TODO-lang
```ruby
obj.m=1 # obj.m = 1 (not obj.m=)
obj.m!=1 # obj.m != 1 (not obj.m!)
```
@@ -1830,7 +1830,7 @@ Usually, only the data would be separated to a list or a hash
in order to keep the code short.


```TODO-lang
```c
/* convert the code to data */
struct entry {char *name; int symbol;};
struct entry *table[] = {
@@ -1888,7 +1888,7 @@ The definition of `struct kwtable` is as follows:

<p class="caption">▼ `kwtable` </p>

```TODO-lang
```
1 struct kwtable {char *name; int id[2]; enum lex_state state;};
(keywords)
@@ -1906,7 +1906,7 @@ This is the place where actually looking up.

<p class="caption">▼ `yylex()` -- identifier -- call `rb_reserved_word()` </p>

```TODO-lang
```yacc
4173 struct kwtable *kw;
4174
4175 /* See if it is a reserved word. */
@@ -1927,7 +1927,7 @@ The double quote (`"`) part of `yylex()` is this.

<p class="caption">▼ `yylex` − `'"'` </p>

```TODO-lang
```yacc
3318 case '"':
3319 lex_strterm = NEW_STRTERM(str_dquote, '"', 0);
3320 return tSTRING_BEG;
@@ -1943,7 +1943,7 @@ Then, this time, when taking a look at the rule,

<p class="caption">▼ rules for strings </p>

```TODO-lang
```yacc
string1 : tSTRING_BEG string_contents tSTRING_END
string_contents :
@@ -1968,7 +1968,7 @@ These rules are the part introduced to deal with embedded expressions inside of
`tSTRING_DVAR` represents "`#` that in front of a variable". For example,


```TODO-lang
```ruby
".....#$gvar...."
```

@@ -1995,7 +1995,7 @@ the next `yylex()`.
What plays an important role there is ...


```TODO-lang
```yacc
case '"':
lex_strterm = NEW_STRTERM(str_dquote, '"', 0);
return tSTRING_BEG;
@@ -2007,7 +2007,7 @@ What plays an important role there is ...

<p class="caption">▼ the beginning of `yylex()` </p>

```TODO-lang
```yacc
3106 static int
3107 yylex()
3108 {
@@ -2040,7 +2040,7 @@ This is done in the following part:

<p class="caption">▼ `string_content` </p>

```TODO-lang
```yacc
1916 string_content : ....
1917 | tSTRING_DBEG term_push
1918 {
@@ -2099,7 +2099,7 @@ First, let's look at its type.

<p class="caption">▼ `lex_strterm`</p>

```TODO-lang
```yacc
72 static NODE *lex_strterm;
(parse.y)
@@ -2116,7 +2116,7 @@ you should remember only these two points.

<p class="caption">▼ `NEW_STRTERM()`</p>

```TODO-lang
```yacc
2865 #define NEW_STRTERM(func, term, paren) \
2866 rb_node_newnode(NODE_STRTERM, (func), (term), (paren))
@@ -2133,7 +2133,7 @@ and if it is a `'` string, it is `'`.
`paren` is used to store the corresponding parenthesis when it is a `%` string.
For example,

```TODO-lang
```ruby
%Q(..........)
```

@@ -2148,7 +2148,7 @@ The available types are decided as follows:

<p class="caption">▼ `func`</p>

```TODO-lang
```yacc
2775 #define STR_FUNC_ESCAPE 0x01 /* backslash notations such as \n are in effect */
2776 #define STR_FUNC_EXPAND 0x02 /* embedded expressions are in effect */
2777 #define STR_FUNC_REGEXP 0x04 /* it is a regular expression */
@@ -2170,13 +2170,14 @@ The available types are decided as follows:

Each meaning of `enum string_type` is as follows:


| `str_squote` | `'` string / `%q` |
| `str_dquote` | `"` string / `%Q` |
| Type | Meaning |
| ------------ | ---------------------------------------------- |
| `str_squote` | `'` string / `%q` |
| `str_dquote` | `"` string / `%Q` |
| `str_xquote` | command string (not be explained in this book) |
| `str_regexp` | regular expression |
| `str_sword` | `%w` |
| `str_dword` | `%W` |
| `str_regexp` | regular expression |
| `str_sword` | `%w` |
| `str_dword` | `%W` |



@@ -2189,7 +2190,7 @@ in other words, the `if` at the beginning.

<p class="caption">▼ `yylex`− string</p>

```TODO-lang
```yacc
3114 if (lex_strterm) {
3115 int token;
3116 if (nd_type(lex_strterm) == NODE_HEREDOC) {
@@ -2242,7 +2243,7 @@ First, I'll show the code of `yylex()` to scan the starting symbol of a here doc

<p class="caption">▼ `yylex`−`'&lt;'`</p>

```TODO-lang
```yacc
3260 case '<':
3261 c = nextc();
3262 if (c == '<' &&
@@ -2267,7 +2268,7 @@ Therefore, here is `heredoc_identifier()`.

<p class="caption">▼ `heredoc_identifier()`</p>

```TODO-lang
```yacc
2926 static int
2927 heredoc_identifier()
2928 {
@@ -2292,8 +2293,8 @@ Until now, the input buffer probably has become as depicted as Figure 10.
Let's recall that the input buffer reads a line at a time.

<figure>
<img src="images/ch_parser_lexparams.jpg" alt="figure 10: scanning `"printf\(<<EOS,n\">
<figcaption>figure 10: scanning `"printf\(<<EOS,n\</figcaption>
<img src="images/ch_parser_lexparams.jpg" alt="scanning `&quot;printf(<<EOS,n)&quot;`">
<figcaption>scanning <code class=inline>"printf(<<EOS,n)"</code></figcaption>
</figure>


@@ -2309,7 +2310,7 @@ read line) and `len` (the length that has already read) are saved.
Then, the dynamic call graph before and after `heredoc_identifier` is simply
shown below:

```TODO-lang
```
yyparse
yylex(case '<')
heredoc_identifier(lex_strterm = ....)
@@ -2326,7 +2327,7 @@ Notice that `lex_strterm` remains unchanged after it was set at `heredoc_identif

<p class="caption">▼ `here_document()`(simplified)</p>

```TODO-lang
```yacc
here_document(NODE *here)
{
VALUE line; /* the line currently being scanned */
@@ -2371,7 +2372,7 @@ And finally, leaving the `do` ~ `while` loop, it is `heredoc_restore()`.

<p class="caption">▼ `heredoc_restore()` </p>

```TODO-lang
```yacc
2990 static void
2991 heredoc_restore(here)
2992 NODE *here;
246 changes: 123 additions & 123 deletions spec.md

Large diffs are not rendered by default.