rubex 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +1 -0
- data/CONTRIBUTING.md +73 -9
- data/HISTORY.md +19 -0
- data/README.md +53 -8
- data/REFERENCE.md +112 -44
- data/benchmarks/no_gil/no_gil.rb +24 -0
- data/benchmarks/no_gil/no_gil.rubex +22 -0
- data/bin/rubex +1 -1
- data/examples/c_struct_interface/c_struct_interface.rubex +1 -0
- data/lib/rubex.rb +1 -0
- data/lib/rubex/ast.rb +11 -7
- data/lib/rubex/ast/expression.rb +1 -1
- data/lib/rubex/ast/expression/actual_arg_list.rb +7 -0
- data/lib/rubex/ast/expression/analysed_element_ref/c_var_element_ref.rb +5 -2
- data/lib/rubex/ast/expression/analysed_element_ref/ruby_object_element_ref.rb +26 -9
- data/lib/rubex/ast/expression/binary/binary_boolean.rb +1 -1
- data/lib/rubex/ast/expression/binary/binary_expo.rb +34 -0
- data/lib/rubex/ast/expression/binary/colon2.rb +34 -0
- data/lib/rubex/ast/expression/binary/empty_classes.rb +0 -3
- data/lib/rubex/ast/expression/command_call.rb +24 -0
- data/lib/rubex/ast/{statement → expression/command_call}/print.rb +4 -5
- data/lib/rubex/ast/{statement → expression/command_call}/raise.rb +29 -24
- data/lib/rubex/ast/expression/command_call/require.rb +27 -0
- data/lib/rubex/ast/expression/command_call/yield.rb +36 -0
- data/lib/rubex/ast/expression/element_ref.rb +10 -5
- data/lib/rubex/ast/expression/instance_var.rb +33 -0
- data/lib/rubex/ast/expression/method_call.rb +4 -2
- data/lib/rubex/ast/expression/method_call/c_function_call.rb +4 -3
- data/lib/rubex/ast/expression/method_call/ruby_method_call.rb +7 -5
- data/lib/rubex/ast/expression/name.rb +10 -1
- data/lib/rubex/ast/expression/ruby_object_element_ref/ruby_array_element_ref.rb +5 -2
- data/lib/rubex/ast/expression/ruby_object_element_ref/ruby_hash_element_ref.rb +10 -2
- data/lib/rubex/ast/expression/to_ruby_object.rb +1 -0
- data/lib/rubex/ast/expression/unary.rb +7 -3
- data/lib/rubex/ast/expression/unary_base/ampersand.rb +5 -0
- data/lib/rubex/ast/node.rb +213 -185
- data/lib/rubex/ast/node/file_node.rb +25 -0
- data/lib/rubex/ast/node/main_node.rb +56 -0
- data/lib/rubex/ast/statement/begin_block/begin.rb +4 -3
- data/lib/rubex/ast/statement/c_array_decl.rb +1 -1
- data/lib/rubex/ast/statement/c_ptr_decl.rb +2 -0
- data/lib/rubex/ast/statement/no_gil_block.rb +70 -0
- data/lib/rubex/ast/statement/return.rb +1 -0
- data/lib/rubex/ast/top_statement.rb +1 -1
- data/lib/rubex/ast/top_statement/klass.rb +4 -0
- data/lib/rubex/ast/top_statement/klass/attached_klass.rb +88 -10
- data/lib/rubex/ast/top_statement/method_def.rb +2 -3
- data/lib/rubex/ast/top_statement/method_def/c_function_def.rb +10 -4
- data/lib/rubex/cli.rb +11 -6
- data/lib/rubex/code_supervisor.rb +49 -0
- data/lib/rubex/code_writer.rb +22 -1
- data/lib/rubex/compiler.rb +109 -30
- data/lib/rubex/compiler_config.rb +14 -1
- data/lib/rubex/constants.rb +3 -0
- data/lib/rubex/data_type.rb +2 -3
- data/lib/rubex/data_type/ruby_object/ruby_symbol.rb +0 -1
- data/lib/rubex/error.rb +4 -0
- data/lib/rubex/helpers/writers.rb +33 -4
- data/lib/rubex/lexer.rex +9 -1
- data/lib/rubex/lexer.rex.rb +15 -2
- data/lib/rubex/parser.racc +125 -49
- data/lib/rubex/parser.racc.rb +1526 -1376
- data/lib/rubex/rake_task.rb +42 -6
- data/lib/rubex/symbol_table/entry.rb +6 -0
- data/lib/rubex/symbol_table/scope.rb +28 -3
- data/lib/rubex/version.rb +1 -1
- data/rubex.gemspec +1 -0
- data/spec/basic_ruby_method_spec.rb +2 -2
- data/spec/blocks_spec.rb +2 -2
- data/spec/box_op_multi_args_spec.rb +34 -0
- data/spec/c_function_ptrs_spec.rb +2 -2
- data/spec/c_functions_spec.rb +2 -0
- data/spec/c_struct_interface_spec.rb +8 -3
- data/spec/default_args_spec.rb +2 -2
- data/spec/external_c_struct_spec.rb +33 -0
- data/spec/fixtures/api/consumer.rubex +0 -0
- data/spec/fixtures/api/implementation.rubex +0 -0
- data/spec/fixtures/api/implementation.rubexd +0 -0
- data/spec/fixtures/box_op_multi_args/box_op_multi_args.rubex +3 -0
- data/spec/fixtures/c_functions/c_functions.rubex +13 -0
- data/spec/fixtures/c_struct_interface/c_struct_interface.rubex +28 -0
- data/spec/fixtures/class_methods/class_methods.rubex +1 -1
- data/spec/fixtures/error_handling/error_handling.rubex +2 -2
- data/spec/fixtures/external_c_struct/external_c_struct.rubex +16 -0
- data/spec/fixtures/if_else/if_else.rubex +1 -1
- data/spec/fixtures/init_ruby_objects_with_literal_syntax/init_ruby_objects_with_literal_syntax.rubex +1 -1
- data/spec/fixtures/instance_variables/instance_variables.rubex +25 -0
- data/spec/fixtures/loops/loops.rubex +2 -2
- data/spec/fixtures/module/module.rubex +28 -0
- data/spec/fixtures/multi_file_programs/Rakefile +8 -0
- data/spec/fixtures/multi_file_programs/a.rubex +5 -0
- data/spec/fixtures/multi_file_programs/b.rubex +5 -0
- data/spec/fixtures/multi_file_programs/multi_file_programs.rubex +14 -0
- data/spec/fixtures/no_gil/no_gil.rubex +24 -0
- data/spec/fixtures/no_gil_attach_class/no_gil_attach_class.rubex +23 -0
- data/spec/fixtures/no_gil_compile_check/no_gil_compile_check.rubex +4 -0
- data/spec/fixtures/outside_stmts/outside_stmts.rubex +6 -0
- data/spec/fixtures/pow/pow.rubex +4 -0
- data/spec/fixtures/rake_task/single_file/test.rubex +3 -0
- data/spec/fixtures/recursion/recursion.rubex +1 -1
- data/spec/fixtures/ruby_constant_scoping/ruby_constant_scoping.rubex +7 -0
- data/spec/fixtures/ruby_operators/ruby_operators.rubex +1 -1
- data/spec/fixtures/ruby_raise/ruby_raise.rubex +2 -2
- data/spec/fixtures/ruby_types/ruby_types.rubex +4 -4
- data/spec/fixtures/statement_expression/statement_expression.rubex +2 -2
- data/spec/fixtures/static_array/static_array.rubex +3 -3
- data/spec/fixtures/string_literals/string_literals.rubex +12 -2
- data/spec/fixtures/struct/struct.rubex +1 -1
- data/spec/fixtures/var_declarations/var_declarations.rubex +1 -1
- data/spec/implicit_lib_include_spec.rb +2 -2
- data/spec/init_ruby_objects_with_literal_syntax_spec.rb +2 -2
- data/spec/instance_variables_spec.rb +33 -0
- data/spec/loops_spec.rb +2 -2
- data/spec/module_spec.rb +39 -0
- data/spec/multi_file_programs_spec.rb +41 -0
- data/spec/no_gil_attach_class_spec.rb +33 -0
- data/spec/no_gil_compile_check_spec.rb +25 -0
- data/spec/no_gil_spec.rb +36 -0
- data/spec/outside_stmts_spec.rb +34 -0
- data/spec/pow_spec.rb +33 -0
- data/spec/rake_task_spec.rb +142 -0
- data/spec/recursion_spec.rb +4 -4
- data/spec/ruby_constant_scoping_spec.rb +42 -0
- data/spec/ruby_raise_spec.rb +2 -2
- data/spec/ruby_symbols_spec.rb +2 -2
- data/spec/ruby_types_spec.rb +2 -2
- data/spec/spec_helper.rb +17 -3
- data/spec/string_literals_spec.rb +1 -0
- metadata +90 -6
- data/lib/rubex/ast/statement/yield.rb +0 -41
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'no_gil.so'
|
2
|
+
require 'benchmark'
|
3
|
+
|
4
|
+
N = 9999999
|
5
|
+
Benchmark.bm do |x|
|
6
|
+
x.report("with") do
|
7
|
+
n = Thread.new { work_with_gil(N) }
|
8
|
+
m = Thread.new { work_with_gil(N) }
|
9
|
+
o = Thread.new { work_with_gil(N) }
|
10
|
+
n.join; m.join; o.join
|
11
|
+
end
|
12
|
+
|
13
|
+
x.report("without") do
|
14
|
+
n = Thread.new { work_without_gil(N) }
|
15
|
+
m = Thread.new { work_without_gil(N) }
|
16
|
+
o = Thread.new { work_without_gil(N) }
|
17
|
+
n.join; m.join; o.join
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# BENCHMARKS
|
22
|
+
# user system total real
|
23
|
+
# with 2.730000 0.000000 2.730000 ( 2.731592)
|
24
|
+
# without 2.990000 0.000000 2.990000 ( 1.076090)
|
@@ -0,0 +1,22 @@
|
|
1
|
+
cfunc void _work_without_gil(double n) no_gil
|
2
|
+
while n > 0 do
|
3
|
+
n ** 0.5 + 4
|
4
|
+
n -= 1
|
5
|
+
end
|
6
|
+
end
|
7
|
+
|
8
|
+
def work_without_gil(n)
|
9
|
+
double i = n
|
10
|
+
no_gil
|
11
|
+
_work_without_gil(i)
|
12
|
+
end
|
13
|
+
|
14
|
+
return i
|
15
|
+
end
|
16
|
+
|
17
|
+
def work_with_gil(double n)
|
18
|
+
while n > 0 do
|
19
|
+
n ** 0.5 + 4
|
20
|
+
n -= 1
|
21
|
+
end
|
22
|
+
end
|
data/bin/rubex
CHANGED
data/lib/rubex.rb
CHANGED
data/lib/rubex/ast.rb
CHANGED
@@ -1,7 +1,11 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
require
|
1
|
+
require_relative 'helpers'
|
2
|
+
require_relative 'ast/statement'
|
3
|
+
require_relative 'ast/expression'
|
4
|
+
Dir[File.join(File.dirname(File.dirname(__FILE__)),
|
5
|
+
"rubex", "ast", "statement", "**", "*.rb" )].sort.each { |f| require f }
|
6
|
+
Dir[File.join(File.dirname(File.dirname(__FILE__)),
|
7
|
+
"rubex", "ast", "expression", "**", "*.rb" )].sort.each { |f| require f }
|
8
|
+
require_relative 'ast/top_statement'
|
9
|
+
require_relative 'ast/node'
|
10
|
+
Dir[File.join(File.dirname(File.dirname(__FILE__)),
|
11
|
+
"rubex", "ast", "node", "**", "*.rb" )].sort.each { |f| require f }
|
data/lib/rubex/ast/expression.rb
CHANGED
@@ -14,7 +14,7 @@ module Rubex
|
|
14
14
|
|
15
15
|
# If the typecast exists, the typecast is made the overall type of
|
16
16
|
# the expression.
|
17
|
-
def analyse_types local_scope
|
17
|
+
def analyse_types local_scope, extern: false
|
18
18
|
if @typecast
|
19
19
|
@typecast.analyse_types(local_scope)
|
20
20
|
@type = @typecast.type
|
@@ -27,6 +27,13 @@ module Rubex
|
|
27
27
|
end
|
28
28
|
end
|
29
29
|
|
30
|
+
def analyse_for_target_type(arg_list, local_scope)
|
31
|
+
@args.each_with_index do |arg, i|
|
32
|
+
arg.analyse_for_target_type arg_list[i].type, local_scope
|
33
|
+
@subexprs << arg
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
30
37
|
def generate_evaluation_code(code, local_scope)
|
31
38
|
@args.each { |a| a.generate_evaluation_code(code, local_scope) }
|
32
39
|
end
|
@@ -3,13 +3,16 @@ module Rubex
|
|
3
3
|
module Expression
|
4
4
|
class CVarElementRef < AnalysedElementRef
|
5
5
|
def analyse_types(local_scope)
|
6
|
+
if @pos.size > 1
|
7
|
+
raise "C array can only accept 1 arg. Not #{@pos.size}"
|
8
|
+
end
|
6
9
|
@pos.analyse_types local_scope
|
7
10
|
@subexprs << @pos
|
8
11
|
end
|
9
12
|
|
10
13
|
def generate_evaluation_code(code, local_scope)
|
11
14
|
generate_and_dispose_subexprs(code, local_scope) do
|
12
|
-
@c_code = "#{@entry.c_name}[#{@pos.c_code(local_scope)}]"
|
15
|
+
@c_code = "#{@entry.c_name}[#{@pos[0].c_code(local_scope)}]"
|
13
16
|
end
|
14
17
|
end
|
15
18
|
|
@@ -19,7 +22,7 @@ module Rubex
|
|
19
22
|
|
20
23
|
def generate_assignment_code(rhs, code, local_scope)
|
21
24
|
generate_and_dispose_subexprs(code, local_scope) do
|
22
|
-
code << "#{@entry.c_name}[#{@pos.c_code(local_scope)}] = "
|
25
|
+
code << "#{@entry.c_name}[#{@pos[0].c_code(local_scope)}] = "
|
23
26
|
code << "#{rhs.c_code(local_scope)};"
|
24
27
|
code.nl
|
25
28
|
end
|
@@ -5,7 +5,7 @@ module Rubex
|
|
5
5
|
def analyse_types(local_scope)
|
6
6
|
super
|
7
7
|
@has_temp = true
|
8
|
-
@pos
|
8
|
+
@pos.map! { |a| a.to_ruby_object }
|
9
9
|
@pos.allocate_temps local_scope
|
10
10
|
@pos.release_temps local_scope
|
11
11
|
@subexprs << @pos
|
@@ -13,26 +13,43 @@ module Rubex
|
|
13
13
|
|
14
14
|
def generate_evaluation_code(code, local_scope)
|
15
15
|
generate_and_dispose_subexprs(code, local_scope) do
|
16
|
-
|
17
|
-
code << "#{@
|
16
|
+
@pos.each { |a| a.generate_evaluation_code(code, local_scope) }
|
17
|
+
code << "#{@c_code} = rb_funcall(#{@entry.c_name}, rb_intern(\"[]\"), "
|
18
|
+
code << @pos.size.to_s
|
19
|
+
@pos.each do |p|
|
20
|
+
code << ", #{p.c_code(local_scope)}"
|
21
|
+
end
|
22
|
+
code << ", NULL" if @pos.empty?
|
23
|
+
code << ");"
|
18
24
|
code.nl
|
19
25
|
end
|
20
26
|
end
|
21
27
|
|
28
|
+
# Generate code for calls to array_ref inside structs.
|
22
29
|
def generate_element_ref_code(expr, code, local_scope)
|
23
30
|
generate_and_dispose_subexprs(code, local_scope) do
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
31
|
+
@pos.each { |a| a.generate_evaluation_code(code, local_scope) }
|
32
|
+
code << "#{@c_code} = rb_funcall(#{expr.c_code(local_scope)}."
|
33
|
+
code << "#{@entry.c_name}, rb_intern(\"[]\"), #{@pos.size}"
|
34
|
+
@pos.each do |p|
|
35
|
+
code << ", #{p.c_code(local_scope)}"
|
36
|
+
end
|
37
|
+
code << ", NULL" if @pos.empty?
|
38
|
+
code << ");"
|
28
39
|
code.nl
|
29
40
|
end
|
30
41
|
end
|
31
42
|
|
32
43
|
def generate_assignment_code(rhs, code, local_scope)
|
44
|
+
raise "must specify atleast 1 arg in Object#[]=" if @pos.size < 1
|
33
45
|
generate_and_dispose_subexprs(code, local_scope) do
|
34
|
-
|
35
|
-
code << "#{@
|
46
|
+
@pos.each { |a| a.generate_evaluation_code(code, local_scope) }
|
47
|
+
code << "rb_funcall(#{@entry.c_name}, rb_intern(\"[]=\"),"
|
48
|
+
code << "#{@pos.size + 1}"
|
49
|
+
@pos.each do |p|
|
50
|
+
code << ", #{p.c_code(local_scope)}"
|
51
|
+
end
|
52
|
+
code << ", #{rhs.c_code(local_scope)});"
|
36
53
|
code.nl
|
37
54
|
end
|
38
55
|
end
|
@@ -4,7 +4,7 @@ module Rubex
|
|
4
4
|
class BinaryBoolean < Binary
|
5
5
|
def analyse_types(local_scope)
|
6
6
|
@left.analyse_types local_scope
|
7
|
-
@right.
|
7
|
+
@right.analyse_for_target_type @left.type, local_scope
|
8
8
|
if type_of(@left).object? || type_of(@right).object?
|
9
9
|
|
10
10
|
@left = @left.to_ruby_object
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Rubex
|
2
|
+
module AST
|
3
|
+
module Expression
|
4
|
+
class BinaryExpo < Binary
|
5
|
+
def analyse_types(local_scope)
|
6
|
+
@left.analyse_types local_scope
|
7
|
+
@right.analyse_types local_scope
|
8
|
+
if type_of(@left).object? || type_of(@right).object?
|
9
|
+
@left = @left.to_ruby_object
|
10
|
+
@right = @right.to_ruby_object
|
11
|
+
@subexprs << @left
|
12
|
+
@subexprs << @right
|
13
|
+
else
|
14
|
+
@type = Rubex::DataType::F64.new
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
def generate_evaluation_code code, local_scope
|
20
|
+
generate_and_dispose_subexprs(code, local_scope) do
|
21
|
+
if @type.object?
|
22
|
+
code << "#{@c_code} = rb_funcall(#{@left.c_code(local_scope)}," +
|
23
|
+
"rb_intern(\"#{@operator}\")," +
|
24
|
+
"1, #{@right.c_code(local_scope)});"
|
25
|
+
code.nl
|
26
|
+
else
|
27
|
+
@c_code = "( pow(#{@left.c_code(local_scope)}, #{@right.c_code(local_scope)}) )"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Rubex
|
2
|
+
module AST
|
3
|
+
module Expression
|
4
|
+
class Colon2 < Base
|
5
|
+
attr_reader :lhs, :rhs
|
6
|
+
|
7
|
+
def initialize lhs, rhs
|
8
|
+
@lhs = lhs
|
9
|
+
@rhs = rhs
|
10
|
+
end
|
11
|
+
|
12
|
+
def analyse_types local_scope
|
13
|
+
@type = DataType::RubyObject.new
|
14
|
+
end
|
15
|
+
|
16
|
+
def generate_evaluation_code code, local_scope
|
17
|
+
@c_code = recursive_scoping_generation @lhs, @rhs, "rb_const_get(CLASS_OF(#{local_scope.self_name}), rb_intern(\"#{@lhs}\"))"
|
18
|
+
end
|
19
|
+
|
20
|
+
def recursive_scoping_generation lhs, rhs, c_str
|
21
|
+
if rhs.is_a?(Colon2)
|
22
|
+
recursive_scoping_generation rhs.lhs, rhs.rhs, "rb_const_get(#{c_str}, rb_intern(\"#{rhs.lhs}\"))"
|
23
|
+
else
|
24
|
+
"rb_const_get(#{c_str}, rb_intern(\"#{rhs}\"))"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def c_code local_scope
|
29
|
+
super + @c_code
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -57,11 +57,35 @@ module Rubex
|
|
57
57
|
@entry && @entry.type.base_type.c_function?
|
58
58
|
end
|
59
59
|
|
60
|
+
def raise_call?
|
61
|
+
!@entry && @command == "raise"
|
62
|
+
end
|
63
|
+
|
64
|
+
def yield_call?
|
65
|
+
!@entry && @command == "yield"
|
66
|
+
end
|
67
|
+
|
68
|
+
def print_call?
|
69
|
+
!@entry && @command == "print"
|
70
|
+
end
|
71
|
+
|
72
|
+
def require_call?
|
73
|
+
!@entry && @command == "require"
|
74
|
+
end
|
75
|
+
|
60
76
|
def analyse_command_type(local_scope)
|
61
77
|
if struct_member_call?
|
62
78
|
@command = Expression::StructOrUnionMemberCall.new @expr, @command, @arg_list
|
63
79
|
elsif c_function_call?
|
64
80
|
@command = Expression::CFunctionCall.new @expr, @command, @arg_list
|
81
|
+
elsif raise_call?
|
82
|
+
@command = Expression::Raise.new @arg_list
|
83
|
+
elsif yield_call?
|
84
|
+
@command = Expression::Yield.new @arg_list
|
85
|
+
elsif print_call?
|
86
|
+
@command = Expression::Print.new @arg_list
|
87
|
+
elsif require_call?
|
88
|
+
@command = Expression::Require.new @arg_list
|
65
89
|
else
|
66
90
|
@command = Expression::RubyMethodCall.new @expr, @command, @arg_list
|
67
91
|
end
|
@@ -1,13 +1,12 @@
|
|
1
1
|
module Rubex
|
2
2
|
module AST
|
3
|
-
module
|
3
|
+
module Expression
|
4
4
|
class Print < Base
|
5
|
-
def initialize(expressions
|
6
|
-
super(location)
|
5
|
+
def initialize(expressions)
|
7
6
|
@expressions = expressions
|
8
7
|
end
|
9
8
|
|
10
|
-
def
|
9
|
+
def analyse_types(local_scope)
|
11
10
|
@expressions.each do |expr|
|
12
11
|
expr.analyse_types local_scope
|
13
12
|
expr.allocate_temps local_scope
|
@@ -15,7 +14,7 @@ module Rubex
|
|
15
14
|
end
|
16
15
|
end
|
17
16
|
|
18
|
-
def
|
17
|
+
def generate_evaluation_code(code, local_scope)
|
19
18
|
super
|
20
19
|
@expressions.each do |expr|
|
21
20
|
expr.generate_evaluation_code code, local_scope
|
@@ -1,44 +1,49 @@
|
|
1
1
|
module Rubex
|
2
2
|
module AST
|
3
|
-
module
|
4
|
-
class Raise <
|
3
|
+
module Expression
|
4
|
+
class Raise < CommandCall
|
5
5
|
def initialize(args)
|
6
6
|
@args = args
|
7
7
|
end
|
8
8
|
|
9
|
-
def
|
9
|
+
def analyse_types(local_scope)
|
10
10
|
@args.analyse_types local_scope
|
11
11
|
@args.allocate_temps local_scope
|
12
|
-
@args.release_temps local_scope
|
13
12
|
unless @args.empty? || @args[0].is_a?(AST::Expression::Name) ||
|
14
13
|
@args[0].is_a?(AST::Expression::Literal::StringLit)
|
15
14
|
raise Rubex::TypeMismatchError, "Wrong argument list #{@args.inspect} for raise."
|
16
15
|
end
|
16
|
+
@subexprs = [@args]
|
17
|
+
@args.release_temps local_scope
|
17
18
|
end
|
18
19
|
|
19
|
-
def
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
def generate_evaluation_code(code, local_scope)
|
21
|
+
generate_and_dispose_subexprs(code, local_scope) do
|
22
|
+
@c_code = ''
|
23
|
+
@c_code << 'rb_raise('
|
23
24
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
25
|
+
if @args[0].is_a?(AST::Expression::Name)
|
26
|
+
@c_code << @args[0].c_code(local_scope) + ','
|
27
|
+
args = @args[1..-1]
|
28
|
+
else
|
29
|
+
@c_code << Rubex::DEFAULT_CLASS_MAPPINGS['RuntimeError'] + ','
|
30
|
+
args = @args
|
31
|
+
end
|
31
32
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
33
|
+
unless args.empty?
|
34
|
+
@c_code << "\"#{prepare_format_string(args)}\" ,"
|
35
|
+
@c_code << args.map { |arg| (inspected_expr(arg, local_scope)).to_s }.join(',')
|
36
|
+
else
|
37
|
+
@c_code << '""'
|
38
|
+
end
|
39
|
+
@c_code << ');'
|
37
40
|
end
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
41
|
+
end
|
42
|
+
|
43
|
+
def generate_disposal_code(code); end
|
44
|
+
|
45
|
+
def c_code(_local_scope)
|
46
|
+
super + @c_code
|
42
47
|
end
|
43
48
|
|
44
49
|
private
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Rubex
|
2
|
+
module AST
|
3
|
+
module Expression
|
4
|
+
class Require < Base
|
5
|
+
def initialize args
|
6
|
+
@args = args
|
7
|
+
end
|
8
|
+
|
9
|
+
def analyse_types(local_scope)
|
10
|
+
raise "require can only support single string argument." if @args.size > 1
|
11
|
+
if !@args[0].is_a?(Expression::Literal::StringLit)
|
12
|
+
raise "Argument to require must be a string literal. not #{@args[0].class}."
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def generate_evaluation_code(code, local_scope)
|
17
|
+
string = @args[0].instance_variable_get(:@name)
|
18
|
+
@c_code = "rb_funcall(rb_cObject, rb_intern(\"require\"), 1, rb_str_new2(\"#{string}\"))"
|
19
|
+
end
|
20
|
+
|
21
|
+
def c_code(_local_scope)
|
22
|
+
@c_code
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|