rubex 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (131) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +1 -0
  3. data/CONTRIBUTING.md +73 -9
  4. data/HISTORY.md +19 -0
  5. data/README.md +53 -8
  6. data/REFERENCE.md +112 -44
  7. data/benchmarks/no_gil/no_gil.rb +24 -0
  8. data/benchmarks/no_gil/no_gil.rubex +22 -0
  9. data/bin/rubex +1 -1
  10. data/examples/c_struct_interface/c_struct_interface.rubex +1 -0
  11. data/lib/rubex.rb +1 -0
  12. data/lib/rubex/ast.rb +11 -7
  13. data/lib/rubex/ast/expression.rb +1 -1
  14. data/lib/rubex/ast/expression/actual_arg_list.rb +7 -0
  15. data/lib/rubex/ast/expression/analysed_element_ref/c_var_element_ref.rb +5 -2
  16. data/lib/rubex/ast/expression/analysed_element_ref/ruby_object_element_ref.rb +26 -9
  17. data/lib/rubex/ast/expression/binary/binary_boolean.rb +1 -1
  18. data/lib/rubex/ast/expression/binary/binary_expo.rb +34 -0
  19. data/lib/rubex/ast/expression/binary/colon2.rb +34 -0
  20. data/lib/rubex/ast/expression/binary/empty_classes.rb +0 -3
  21. data/lib/rubex/ast/expression/command_call.rb +24 -0
  22. data/lib/rubex/ast/{statement → expression/command_call}/print.rb +4 -5
  23. data/lib/rubex/ast/{statement → expression/command_call}/raise.rb +29 -24
  24. data/lib/rubex/ast/expression/command_call/require.rb +27 -0
  25. data/lib/rubex/ast/expression/command_call/yield.rb +36 -0
  26. data/lib/rubex/ast/expression/element_ref.rb +10 -5
  27. data/lib/rubex/ast/expression/instance_var.rb +33 -0
  28. data/lib/rubex/ast/expression/method_call.rb +4 -2
  29. data/lib/rubex/ast/expression/method_call/c_function_call.rb +4 -3
  30. data/lib/rubex/ast/expression/method_call/ruby_method_call.rb +7 -5
  31. data/lib/rubex/ast/expression/name.rb +10 -1
  32. data/lib/rubex/ast/expression/ruby_object_element_ref/ruby_array_element_ref.rb +5 -2
  33. data/lib/rubex/ast/expression/ruby_object_element_ref/ruby_hash_element_ref.rb +10 -2
  34. data/lib/rubex/ast/expression/to_ruby_object.rb +1 -0
  35. data/lib/rubex/ast/expression/unary.rb +7 -3
  36. data/lib/rubex/ast/expression/unary_base/ampersand.rb +5 -0
  37. data/lib/rubex/ast/node.rb +213 -185
  38. data/lib/rubex/ast/node/file_node.rb +25 -0
  39. data/lib/rubex/ast/node/main_node.rb +56 -0
  40. data/lib/rubex/ast/statement/begin_block/begin.rb +4 -3
  41. data/lib/rubex/ast/statement/c_array_decl.rb +1 -1
  42. data/lib/rubex/ast/statement/c_ptr_decl.rb +2 -0
  43. data/lib/rubex/ast/statement/no_gil_block.rb +70 -0
  44. data/lib/rubex/ast/statement/return.rb +1 -0
  45. data/lib/rubex/ast/top_statement.rb +1 -1
  46. data/lib/rubex/ast/top_statement/klass.rb +4 -0
  47. data/lib/rubex/ast/top_statement/klass/attached_klass.rb +88 -10
  48. data/lib/rubex/ast/top_statement/method_def.rb +2 -3
  49. data/lib/rubex/ast/top_statement/method_def/c_function_def.rb +10 -4
  50. data/lib/rubex/cli.rb +11 -6
  51. data/lib/rubex/code_supervisor.rb +49 -0
  52. data/lib/rubex/code_writer.rb +22 -1
  53. data/lib/rubex/compiler.rb +109 -30
  54. data/lib/rubex/compiler_config.rb +14 -1
  55. data/lib/rubex/constants.rb +3 -0
  56. data/lib/rubex/data_type.rb +2 -3
  57. data/lib/rubex/data_type/ruby_object/ruby_symbol.rb +0 -1
  58. data/lib/rubex/error.rb +4 -0
  59. data/lib/rubex/helpers/writers.rb +33 -4
  60. data/lib/rubex/lexer.rex +9 -1
  61. data/lib/rubex/lexer.rex.rb +15 -2
  62. data/lib/rubex/parser.racc +125 -49
  63. data/lib/rubex/parser.racc.rb +1526 -1376
  64. data/lib/rubex/rake_task.rb +42 -6
  65. data/lib/rubex/symbol_table/entry.rb +6 -0
  66. data/lib/rubex/symbol_table/scope.rb +28 -3
  67. data/lib/rubex/version.rb +1 -1
  68. data/rubex.gemspec +1 -0
  69. data/spec/basic_ruby_method_spec.rb +2 -2
  70. data/spec/blocks_spec.rb +2 -2
  71. data/spec/box_op_multi_args_spec.rb +34 -0
  72. data/spec/c_function_ptrs_spec.rb +2 -2
  73. data/spec/c_functions_spec.rb +2 -0
  74. data/spec/c_struct_interface_spec.rb +8 -3
  75. data/spec/default_args_spec.rb +2 -2
  76. data/spec/external_c_struct_spec.rb +33 -0
  77. data/spec/fixtures/api/consumer.rubex +0 -0
  78. data/spec/fixtures/api/implementation.rubex +0 -0
  79. data/spec/fixtures/api/implementation.rubexd +0 -0
  80. data/spec/fixtures/box_op_multi_args/box_op_multi_args.rubex +3 -0
  81. data/spec/fixtures/c_functions/c_functions.rubex +13 -0
  82. data/spec/fixtures/c_struct_interface/c_struct_interface.rubex +28 -0
  83. data/spec/fixtures/class_methods/class_methods.rubex +1 -1
  84. data/spec/fixtures/error_handling/error_handling.rubex +2 -2
  85. data/spec/fixtures/external_c_struct/external_c_struct.rubex +16 -0
  86. data/spec/fixtures/if_else/if_else.rubex +1 -1
  87. data/spec/fixtures/init_ruby_objects_with_literal_syntax/init_ruby_objects_with_literal_syntax.rubex +1 -1
  88. data/spec/fixtures/instance_variables/instance_variables.rubex +25 -0
  89. data/spec/fixtures/loops/loops.rubex +2 -2
  90. data/spec/fixtures/module/module.rubex +28 -0
  91. data/spec/fixtures/multi_file_programs/Rakefile +8 -0
  92. data/spec/fixtures/multi_file_programs/a.rubex +5 -0
  93. data/spec/fixtures/multi_file_programs/b.rubex +5 -0
  94. data/spec/fixtures/multi_file_programs/multi_file_programs.rubex +14 -0
  95. data/spec/fixtures/no_gil/no_gil.rubex +24 -0
  96. data/spec/fixtures/no_gil_attach_class/no_gil_attach_class.rubex +23 -0
  97. data/spec/fixtures/no_gil_compile_check/no_gil_compile_check.rubex +4 -0
  98. data/spec/fixtures/outside_stmts/outside_stmts.rubex +6 -0
  99. data/spec/fixtures/pow/pow.rubex +4 -0
  100. data/spec/fixtures/rake_task/single_file/test.rubex +3 -0
  101. data/spec/fixtures/recursion/recursion.rubex +1 -1
  102. data/spec/fixtures/ruby_constant_scoping/ruby_constant_scoping.rubex +7 -0
  103. data/spec/fixtures/ruby_operators/ruby_operators.rubex +1 -1
  104. data/spec/fixtures/ruby_raise/ruby_raise.rubex +2 -2
  105. data/spec/fixtures/ruby_types/ruby_types.rubex +4 -4
  106. data/spec/fixtures/statement_expression/statement_expression.rubex +2 -2
  107. data/spec/fixtures/static_array/static_array.rubex +3 -3
  108. data/spec/fixtures/string_literals/string_literals.rubex +12 -2
  109. data/spec/fixtures/struct/struct.rubex +1 -1
  110. data/spec/fixtures/var_declarations/var_declarations.rubex +1 -1
  111. data/spec/implicit_lib_include_spec.rb +2 -2
  112. data/spec/init_ruby_objects_with_literal_syntax_spec.rb +2 -2
  113. data/spec/instance_variables_spec.rb +33 -0
  114. data/spec/loops_spec.rb +2 -2
  115. data/spec/module_spec.rb +39 -0
  116. data/spec/multi_file_programs_spec.rb +41 -0
  117. data/spec/no_gil_attach_class_spec.rb +33 -0
  118. data/spec/no_gil_compile_check_spec.rb +25 -0
  119. data/spec/no_gil_spec.rb +36 -0
  120. data/spec/outside_stmts_spec.rb +34 -0
  121. data/spec/pow_spec.rb +33 -0
  122. data/spec/rake_task_spec.rb +142 -0
  123. data/spec/recursion_spec.rb +4 -4
  124. data/spec/ruby_constant_scoping_spec.rb +42 -0
  125. data/spec/ruby_raise_spec.rb +2 -2
  126. data/spec/ruby_symbols_spec.rb +2 -2
  127. data/spec/ruby_types_spec.rb +2 -2
  128. data/spec/spec_helper.rb +17 -3
  129. data/spec/string_literals_spec.rb +1 -0
  130. metadata +90 -6
  131. data/lib/rubex/ast/statement/yield.rb +0 -41
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA256:
3
- metadata.gz: 742568f609bbfd393f0262b1f8b79089a3e22007053e72714bbb8cc256fd5066
4
- data.tar.gz: 7bd08df3a97cdf480bdb4fa5b34ef37553678f97cbd19f53027296148724c66a
2
+ SHA1:
3
+ metadata.gz: c8859787757dadc4f2cadd8cbb2d227d26ae5f69
4
+ data.tar.gz: bb028214cc70f7fee50d0fd0c185bd89244eb593
5
5
  SHA512:
6
- metadata.gz: 32b17fb06897cf4ca018dd61ba27ee58b6f21d885b715c7ab13effd726175465379912c168c21ba0a7ba48ee69f244996fbb680ae5a33a78021cd07745b6473f
7
- data.tar.gz: febfc14a8dabb0ab050d592f9d50cfeaaf068007cb0635104876cfa679710fd311e4e71d38f4f8cf3019a6ef78e231fa4638381803899e3f4ee499f19312d41c
6
+ metadata.gz: 71322d0c3be4a0acedfa74d11789941c43f5cd81613bd771445f6124e48fa84b22bbdb451de731bdc15df1a534715e1628debdc10334cb468773c584bb992746
7
+ data.tar.gz: 1ec819863e026a14283dfb0d0ffde57df6d29457cb72561f816cc6aa840d29fe01947a1e705550205b5dff30806f1c12873653917ffa1780a9425408dd772d58
data/.gitignore CHANGED
@@ -53,3 +53,4 @@ lib/rubex/parser.output
53
53
  lib/rubex/parser.tab.rb
54
54
  /.idea/
55
55
  TAGS
56
+ parse.y
@@ -31,14 +31,66 @@ Couple of conventions that I followed when writing the code:
31
31
  - analyse_statement(local_scope)
32
32
  - generate_code(code, local_scope)
33
33
  * Expressions contain methods:
34
- - analyse_statement(local_scope)
34
+ - analyse_types(local_scope)
35
35
  - c_code(local_scope)
36
36
 
37
- Sometimes it can so happen that an expression can consist simply of a single variable (like `if (a)`) or be a full expression (like `if (a == b)`). In the first case, the `a` is just read as an `IDENTIFIER` by the parser. In the second case, `a == b` is read as an `expr` and is stored in the AST as `Rubex::AST::Expression`.
38
-
39
- Now you might be thinking why expressions should also have a `analyse_statement` method, that's just for maintaining uniformity between exprs and stmts (maybe that should be just `analyse`?).
40
-
41
- When writing the `<=>` operator under Rubex::DataType classes, I have been forced to assume that `Int` is 32 bits long since I have not yet incorporated a way to figure out the number of bits used by a particular machine for representing an `int`. It will be changed later to make it machine-dependent.
37
+ Sometimes it can so happen that an expression can consist simply of a single variable
38
+ (like `if (a)`) or be a full expression (like `if (a == b)`). In the first case, the
39
+ `a` is just read as an `IDENTIFIER` by the parser. In the second case, `a == b` is
40
+ read as an `expr` and is stored in the AST as `Rubex::AST::Expression`.
41
+
42
+ When writing the `<=>` operator under Rubex::DataType classes, I have been forced to
43
+ assume that `Int` is 32 bits long since I have not yet incorporated a way to figure
44
+ out the number of bits used by a particular machine for representing an `int`.
45
+ It will be changed later to make it machine-dependent.
46
+
47
+ ## Parser particulars
48
+
49
+ Kinds of statements that can be defined at the top:
50
+ * classes.
51
+ * attached classes.
52
+ * modules.
53
+ * ruby/c methods.
54
+ * all kinds of exprs. (command call/binary/unary etc.)
55
+ * if stmts.
56
+ * while.
57
+ * for.
58
+ * c bindings.
59
+ * function declaration.
60
+ * struct or union definition.
61
+ * alias statements.
62
+ * assignment statements.
63
+ * variable decl and init.
64
+ * forward declaration.
65
+
66
+ stmts that can be defined inside other classes:
67
+ * other classes.
68
+ * attached classes.
69
+ * modules.
70
+ * c functions.
71
+ * ruby methods.
72
+ * struct/union definitions.
73
+ * constants.
74
+ * class variables.
75
+ * attr reader/writer/accessor.
76
+ * forward declaration.
77
+
78
+ stmts that can be defined inside other functions/blocks:
79
+ * EVERYTHING _except_:
80
+ - classes.
81
+ - attached classes.
82
+ - modules.
83
+ - ruby/c methods.
84
+ - c bindinds.
85
+
86
+ ## Multi file programs
87
+
88
+ When specifying mutliple rubex files using rake tasks or the command line, rubex will read
89
+ the name of the main file, find the main file and start compiling that first. Whatever
90
+
91
+ Since above approach does not really require user to specify all the files at compile time,
92
+ the 'files' option is only useful when the user is only running the Rubex compiler and not
93
+ generating any binaries.
42
94
 
43
95
  # Important data representations
44
96
 
@@ -52,7 +104,8 @@ This consists of a hash that looks like this:
52
104
  }
53
105
  ```
54
106
 
55
- The `:variables` field might be `nil` in case of a function declaration in which case it is not necessary to specify the name of the variable.
107
+ The `:variables` field might be `nil` in case of a function declaration in which
108
+ case it is not necessary to specify the name of the variable.
56
109
 
57
110
  The `:variables` key maps to a value that is an Array of Hashes that contains a single Hash:
58
111
  ```
@@ -63,7 +116,8 @@ The `:variables` key maps to a value that is an Array of Hashes that contains a
63
116
  }
64
117
  ```
65
118
 
66
- `identity` can be a Hash in case of a function pointer argument, or a simple String in case its an identifier, or an `ElementRef` if specifying an array of elements.
119
+ `identity` can be a Hash in case of a function pointer argument, or a simple String in case
120
+ its an identifier, or an `ElementRef` if specifying an array of elements.
67
121
 
68
122
  If Hash, it will look like this:
69
123
  ```
@@ -78,13 +132,23 @@ If Hash, it will look like this:
78
132
 
79
133
  ## Attach classes
80
134
 
135
+ ## no_gil block code generation
81
136
 
137
+ The generated code for the `no_gil` block has the following components:
138
+ * a function that is namespaced according to the name of the scoping
139
+ function, class and number of no_gil blocks that occur in the function.
140
+ * all the statements that are present in the no_gil block are present in this function.
141
+ * all the variables that are present in the block are made global and are properly
142
+ namespaced accoring to above namespacing criteria.
143
+ * code appropriate for `rb_thread_call_without_gvl` is generated and a pointer to the
144
+ generated function is passed to the function.
145
+ * the new code using the `without_gvl` call is inserted in the place where the `no_gil`
146
+ block was present.
82
147
 
83
148
  # Future work
84
149
 
85
150
  The following features in Rubex need to be implemented or can be made better:
86
151
 
87
- * Ability to have Ruby-style method arguments without parenthesis.
88
152
  * Multiline conditionals in the condition of if-elsif statements.
89
153
  * Special treatment for VALUE C arrays by marking each element with GC.
90
154
  * Checks for return statement. No return statement or wrong return type should raise error/warning.
data/HISTORY.md CHANGED
@@ -1,3 +1,22 @@
1
+ # v0.1.2 (26 May 2018)
2
+
3
+ ## Bug fixes
4
+
5
+ * Fixed bug that prevented proper loading of files from CLI.
6
+
7
+ ## Features
8
+
9
+ * Added `no_gil` block support.
10
+ * Allow creating instance variables.
11
+ * Multiple file Rubex programs using `rubex_require`.
12
+ * Support multiple arguments in `[]` operator.
13
+ * New rake tasks for various options like debug, just compiling, compile + install etc.
14
+ * More CLI options for debug and force.
15
+
16
+ # v0.1.1
17
+
18
+ * Bugs fixes and internal code refactoring. Not much in terms of user-facing features.
19
+
1
20
  # v0.1 (17 Sept. 2017)
2
21
 
3
22
  * First release.
data/README.md CHANGED
@@ -118,19 +118,54 @@ Notice the only difference between the above Rubex code and Ruby is the specific
118
118
  Rubex also takes care of the initial setup and compilation of the C files, so all you need to do is execute a bunch of commands and your extension is up and running!
119
119
 
120
120
  # Installation
121
- To build, requires Ruby version >= 2.3.0
121
+ Requires Ruby version >= 2.3.0
122
122
 
123
- The gem as of now has not reached v0.1. However, you can try it out with:
123
+ Install with:
124
124
  ```
125
- git clone https://github.com/v0dro/rubex.git
126
- cd rubex
127
- bundle install
128
- rake install
125
+ gem install rubex
129
126
  ```
130
127
 
131
128
  # Usage
132
129
 
133
- Installing the gem will also install the `rubex` binary. You can now write a Rubex file (with a `.rubex` file extension) and compile it into C code with:
130
+ Installing the gem will also install the `rubex` binary. You can now write a Rubex file (with a `.rubex` file extension) and compile it into C code using the following commands.
131
+
132
+ ## Commands
133
+
134
+ #### Generate
135
+
136
+ Create all the necessary files for the C extension.
137
+
138
+ ```
139
+ rubex generate file_name.rubex
140
+ ```
141
+
142
+ ```
143
+ Options
144
+ -f, [--force] # replace existing files and directories
145
+ -d, [--dir=DIR] # specify a directory for generating files
146
+ -i, [--install] # automatically run install command after generating Makefile
147
+ -g, [--debug] # enable debugging symbols when compiling with GCC
148
+ ```
149
+
150
+ #### Install
151
+
152
+ Run the `make` utility on generated files.
153
+
154
+ ```
155
+ rubex install path/to/generated/directory
156
+ ```
157
+
158
+ #### Help
159
+
160
+ Describe available commands or one specific command
161
+
162
+ ```
163
+ rubex help [COMMAND]
164
+ ```
165
+
166
+ ## Manual Usage
167
+ If you want to manually generate the files, you can do that with:
168
+
134
169
  ```
135
170
  rubex file_name.rubex
136
171
  ```
@@ -150,6 +185,15 @@ Give yourself 5 min and go through the [TUTORIAL](TUTORIAL.md). Convert a part o
150
185
 
151
186
  Read the full Rubex reference in [REFERENCE](REFERENCE.md).
152
187
 
188
+ # Differences with Ruby
189
+
190
+ Although Rubex tries its best to support the Ruby syntax as much as possible, in some cases it is not feasible or necessary to provide full support. Following is a list of differences between Ruby and Rubex syntax:
191
+
192
+ * All methods in Rubex (including `require` calls) must use round brackets for arguments.
193
+ * No support Ruby blocks.
194
+ * No support for class variables.
195
+ * All methods and functions in Rubex must use the `return` statement for returning values.
196
+
153
197
  # Roadmap
154
198
 
155
199
  See the [CONTRIBUTING](CONTRIBUTING.md) and the GitHub issue tracker for future features.
@@ -157,5 +201,6 @@ See the [CONTRIBUTING](CONTRIBUTING.md) and the GitHub issue tracker for future
157
201
  # Acknowledgements
158
202
 
159
203
  * The Ruby Association (Japan) for providing the initial funding for this project through the Ruby Association Grant 2016.
160
- * Koichi Sasada (@ko1) and Kenta Murata (@mrkn) for their support and mentorship throughout this project.
204
+ * Koichi Sasada (@ko1), Kenta Murata (@mrkn) and Naotoshi Seo (@sonots) for their support and mentorship throughout this project.
161
205
  * Fukuoka Ruby Award 2017.
206
+ * Tokyo Institute of Technology.
@@ -2,59 +2,63 @@
2
2
 
3
3
  Rubex is a language designed to keep you happy even when writing C extension.
4
4
 
5
- # Table of Contents
6
- <!-- MarkdownTOC autolink="true" bracket="round" depth="3"-->
5
+ <!-- markdown-toc start - Don't edit this section. Run M-x markdown-toc-generate-toc again -->
6
+ **Table of Contents**
7
7
 
8
+ - [Rubex (RUBy EXtension Language)](#rubex-ruby-extension-language)
9
+ - [Table of Contents](#table-of-contents)
8
10
  - [Comments](#comments)
9
11
  - [C data types](#c-data-types)
10
- - [Primitive data types](#primitive-data-types)
11
- - [C struct, union and enum](#c-struct-union-and-enum)
12
- - [Forward declarations](#forward-declarations)
13
- - [Pointers](#pointers)
12
+ - [Primitive data types](#primitive-data-types)
13
+ - [C struct, union and enum](#c-struct-union-and-enum)
14
+ - [Forward declarations](#forward-declarations)
15
+ - [Pointers](#pointers)
14
16
  - [Ruby Objects](#ruby-objects)
15
17
  - [Literals](#literals)
16
- - [Integer](#integer)
17
- - [Float](#float)
18
- - [Character](#character)
19
- - [String](#string)
20
- - [Ruby Literals](#ruby-literals)
21
- - [Ruby Symbol](#ruby-symbol)
22
- - [Ruby Array](#ruby-array)
23
- - [Ruby Hash](#ruby-hash)
18
+ - [Integer](#integer)
19
+ - [Float](#float)
20
+ - [Character](#character)
21
+ - [String](#string)
22
+ - [Ruby Literals](#ruby-literals)
23
+ - [Ruby Symbol](#ruby-symbol)
24
+ - [Ruby Array](#ruby-array)
25
+ - [Ruby Hash](#ruby-hash)
24
26
  - [C Functions and Ruby Methods](#c-functions-and-ruby-methods)
25
27
  - [Ruby Constants](#ruby-constants)
26
28
  - [The print statement](#the-print-statement)
27
29
  - [Loops](#loops)
28
- - [The while loop](#the-while-loop)
29
- - [The for loop](#the-for-loop)
30
+ - [The while loop](#the-while-loop)
31
+ - [The for loop](#the-for-loop)
30
32
  - [Conditionals](#conditionals)
31
- - [Important Note](#important-note)
33
+ - [Important Note](#important-note)
32
34
  - [Interfacing C libraries with lib](#interfacing-c-libraries-with-lib)
33
- - [Basic Usage](#basic-usage)
34
- - [Supported declarations](#supported-declarations)
35
- - [Functions](#functions)
36
- - [Variables](#variables)
37
- - [Macros](#macros)
38
- - [Types](#types)
39
- - [Typedefs](#typedefs)
40
- - [Linking Libraries](#linking-libraries)
41
- - [Ready-to-use C functions](#ready-to-use-c-functions)
42
- - [Filename: "rubex/ruby"](#filename-rubexruby)
43
- - [Filename: "rubex/ruby/encoding"](#filename-rubexrubyencoding)
44
- - [Filename: "rubex/stdlib"](#filename-rubexstdlib)
35
+ - [Basic Usage](#basic-usage)
36
+ - [Supported declarations](#supported-declarations)
37
+ - [Functions](#functions)
38
+ - [Variables](#variables)
39
+ - [Macros](#macros)
40
+ - [Types](#types)
41
+ - [Typedefs](#typedefs)
42
+ - [Linking Libraries](#linking-libraries)
43
+ - [Ready-to-use C functions](#ready-to-use-c-functions)
44
+ - [Filename: "rubex/ruby"](#filename-rubexruby)
45
+ - [Filename: "rubex/ruby/encoding"](#filename-rubexrubyencoding)
46
+ - [Filename: "rubex/stdlib"](#filename-rubexstdlib)
45
47
  - [Exception Handling](#exception-handling)
46
48
  - ['Attach' Classes](#attach-classes)
47
- - [The attach keyword](#the-attach-keyword)
48
- - [The data$ variable](#the-data-variable)
49
- - [Special C functions in attach classes](#special-c-functions-in-attach-classes)
50
- - [deallocate](#deallocate)
51
- - [allocate](#allocate)
52
- - [memcount](#memcount)
53
- - [get_struct](#getstruct)
54
- - [gc_mark](#gcmark)
49
+ - [The attach keyword](#the-attach-keyword)
50
+ - [The data$ variable](#the-data-variable)
51
+ - [Special C functions in attach classes](#special-c-functions-in-attach-classes)
52
+ - [deallocate](#deallocate)
53
+ - [allocate](#allocate)
54
+ - [memcount](#memcount)
55
+ - [get_struct](#getstruct)
56
+ - [gc_mark](#gcmark)
55
57
  - [Typecast](#typecast)
56
58
  - [Alias](#alias)
57
59
  - [Conversions between Ruby and C data](#conversions-between-ruby-and-c-data)
60
+ - [Releasing the Global Interpreter Lock](#releasing-the-global-interpreter-lock)
61
+ - [Multi-file rubex programs](#multi-file-rubex-programs)
58
62
  - [C callbacks](#c-callbacks)
59
63
  - [Inline C](#inline-c)
60
64
  - [Handling Strings](#handling-strings)
@@ -62,7 +66,7 @@ Rubex is a language designed to keep you happy even when writing C extension.
62
66
  - [Differences from Ruby](#differences-from-ruby)
63
67
  - [Limitations](#limitations)
64
68
 
65
- <!-- /MarkdownTOC -->
69
+ <!-- markdown-toc end -->
66
70
 
67
71
  # Comments
68
72
 
@@ -640,6 +644,25 @@ The `xfree` function, which is the standard memory freeing function provided by
640
644
 
641
645
  ### allocate
642
646
 
647
+ The `allocate` function is called by the Ruby interpreter before it initializes the class
648
+ using `initialize`. It is here that the C level memory allocations that are assigned to a
649
+ particular class via attached structs should be `xmalloc`'d. The correponding data should be
650
+ freed using `xfree` inside the `deallocate` function that is documented below.
651
+
652
+ Keep in mind that if you choose to define your own `allocate` function, it must have a return
653
+ type `object`. An example `deallocate` would look like so:
654
+ ``` ruby
655
+ struct test
656
+ int *a
657
+ end
658
+
659
+ class A attach test
660
+ cfunc object allocate
661
+ data$.test.a = <int*>xmalloc(sizeof(int)*100)
662
+ end
663
+ end
664
+ ```
665
+
643
666
  ### memcount
644
667
 
645
668
  ### get_struct
@@ -681,7 +704,43 @@ end
681
704
 
682
705
  # Conversions between Ruby and C data
683
706
 
684
- Rubex will implicitly convert most primitive C types like `char`, `int` and `float` to their equivalent Ruby types and vice versa. However, types conversions for user defined types like structs and unions are not supported.
707
+ Rubex will implicitly convert most primitive C types like `char`, `int` and `float`
708
+ to their equivalent Ruby types and vice versa. However, types conversions for user
709
+ defined types like structs and unions are not supported.
710
+
711
+ # Releasing the Global Interpreter Lock
712
+
713
+ Rubex can release the GIL a very simple `no_gil` construct. Some care must be taken when
714
+ using other functions inside this block. As a rule you cannot use any Ruby objects
715
+ inside a `no_gil` block. All data handling must be done _only_ by C data types.
716
+
717
+ Functions that are called inside the `no_gil` block cannot use any Ruby objects either, and
718
+ must be tagged using the `no_gil` keyword. This will ensure that Rubex checks for Ruby
719
+ objects inside these functions and raises an error if you accidentally use Ruby objects. Note
720
+ that these checks are not exhaustive and the user should be careful.
721
+
722
+ Here's an example of using a `no_gil` block from a Ruby method:
723
+ ``` ruby
724
+ cfunc void _work_without_gil(double n) no_gil
725
+ while n > 0 do
726
+ n ** 0.5 + 4
727
+ n -= 1
728
+ end
729
+ end
730
+
731
+ def work_without_gil(n)
732
+ double i = n
733
+ no_gil
734
+ _work_without_gil(i)
735
+ end
736
+
737
+ return i
738
+ end
739
+ ```
740
+
741
+ # Multi-file rubex programs
742
+
743
+
685
744
 
686
745
  # C callbacks
687
746
 
@@ -729,14 +788,23 @@ end
729
788
 
730
789
  # Handling Strings
731
790
 
732
- For purposes of optimization and compatibility with C, Rubex makes certain assumptions about strings. When you assign a Ruby object to a `char*`, Rubex will automatically pass a pointer to the C string contained inside the object to the `char*`, thereby increasing the efficiency of operations on the string. The resulting string is a regular `\0` delimited C string.
791
+ For purposes of optimization and compatibility with C, Rubex makes certain
792
+ assumptions about strings. When you assign a Ruby object to a `char*`, Rubex
793
+ will automatically pass a pointer to the C string contained inside the object
794
+ to the `char*`, thereby increasing the efficiency of operations on the string.
795
+ The resulting string is a regular `\0` delimited C string.
733
796
 
734
- It should be noted that strings MUST use the double quotation syntax (`""`) and not single quotes in all cases. Single quote is reserved for use by C `char` data. For example, to assign a literal value to a C char, you can write `char a = 'b'`, to assign a literal C string to a `char*` array, use `char* a = "hello"`.
797
+ It should be noted that strings MUST use the double quotation syntax (`""`) and
798
+ not single quotes in all cases. Single quote is reserved for use by C `char` data.
799
+ For example, to assign a literal value to a C char, you can write `char a = 'b'`,
800
+ to assign a literal C string to a `char*` array, use `char* a = "hello"`.
735
801
 
736
802
  # Differences from C
737
803
 
738
- * Rubex does not have dereferencing operator (`*`). Instead use `[0]` to access values pointed to by pointers.
739
- * There is no `->` operator for accessing struct elements from a pointer to a struct. Use the `.` operator directly.
804
+ * Rubex does not have dereferencing operator (`*`). Instead use `[0]` to access
805
+ values pointed to by pointers.
806
+ * There is no `->` operator for accessing struct elements from a pointer to a struct.
807
+ Use the `.` operator directly.
740
808
 
741
809
  # Differences from Ruby
742
810
 
@@ -750,4 +818,4 @@ It should be noted that strings MUST use the double quotation syntax (`""`) and
750
818
  Most of the below limitations are temporary and will be taken care of in future versions:
751
819
 
752
820
  * The `require` statement is currently not supported.
753
- * Multi-file Rubex programs are not yet possible.
821
+ * Multi-file Rubex programs are not yet possible.