bakkdoor-blocktalk 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. data/LICENSE +165 -0
  2. data/README.markdown +114 -0
  3. data/TODO +9 -0
  4. data/benchmark.bt +18 -0
  5. data/evaluator.rb +19 -0
  6. data/examples/chained_method_call.bt +15 -0
  7. data/examples/classes_modules.bt +68 -0
  8. data/examples/exceptions.bt +28 -0
  9. data/examples/fac.bt +23 -0
  10. data/examples/inline_ruby.bt +20 -0
  11. data/examples/linecounter.bt +8 -0
  12. data/examples/multiple_methodcall.bt +1 -0
  13. data/examples/portscan.bt +39 -0
  14. data/examples/require.bt +8 -0
  15. data/examples/ruby_methods.bt +20 -0
  16. data/examples/string_interpol.bt +10 -0
  17. data/examples/string_test.bt +13 -0
  18. data/examples/test.bt +45 -0
  19. data/examples/test2.bt +125 -0
  20. data/examples/test3.bt +9 -0
  21. data/grammar/blocktalk.rb +5030 -0
  22. data/grammar/blocktalk.tt +463 -0
  23. data/language-spec/blocktalk-example.bt +38 -0
  24. data/language-spec/blocktalk-lang-spec.bt +232 -0
  25. data/lib/blocktalk/array.bt +60 -0
  26. data/lib/blocktalk/string.bt +9 -0
  27. data/lib/blocktalk.bt +3 -0
  28. data/lib/core.rb +12 -0
  29. data/lib/kernel/array.rb +9 -0
  30. data/lib/kernel/class.rb +46 -0
  31. data/lib/kernel/codeblock.rb +57 -0
  32. data/lib/kernel/console.rb +40 -0
  33. data/lib/kernel/error.rb +11 -0
  34. data/lib/kernel/module.rb +18 -0
  35. data/lib/kernel/object.rb +66 -0
  36. data/lib/kernel/string.rb +5 -0
  37. data/lib/kernel/system.rb +5 -0
  38. data/parser/helpers/method_definitions.rb +31 -0
  39. data/parser/helpers/methodcalls.rb +56 -0
  40. data/parser/nodes/block_literal.rb +42 -0
  41. data/parser/nodes/catch.rb +22 -0
  42. data/parser/nodes/class_method_definition.rb +15 -0
  43. data/parser/nodes/comment.rb +7 -0
  44. data/parser/nodes/ensure.rb +7 -0
  45. data/parser/nodes/expression.rb +7 -0
  46. data/parser/nodes/identifier.rb +7 -0
  47. data/parser/nodes/integer_literal.rb +7 -0
  48. data/parser/nodes/message_receiver.rb +7 -0
  49. data/parser/nodes/message_with_params.rb +8 -0
  50. data/parser/nodes/message_without_params.rb +10 -0
  51. data/parser/nodes/method_definition.rb +31 -0
  52. data/parser/nodes/methodcall.rb +37 -0
  53. data/parser/nodes/multiple_methodcall.rb +28 -0
  54. data/parser/nodes/operator_message.rb +8 -0
  55. data/parser/nodes/require.rb +25 -0
  56. data/parser/nodes/return.rb +7 -0
  57. data/parser/nodes/root.rb +15 -0
  58. data/parser/nodes/string.rb +7 -0
  59. data/parser/nodes/subexpression.rb +7 -0
  60. data/parser/nodes/super_call.rb +12 -0
  61. data/parser/nodes/try.rb +7 -0
  62. data/parser/nodes/yield.rb +18 -0
  63. data/parser/nodes.rb +29 -0
  64. metadata +70 -3
@@ -0,0 +1,42 @@
1
+ module Blocktalk
2
+ class BlockLiteralNode < Treetop::Runtime::SyntaxNode
3
+ def value
4
+ block_str = "Codeblock.new("
5
+
6
+ ruby_params_string = "" # for ruby params list to block
7
+
8
+ if params.respond_to?(:value)
9
+ ruby_params_string += "|"
10
+ names_and_identifiers = params.value
11
+
12
+ param_names = []
13
+ param_identifiers = []
14
+
15
+ names_and_identifiers.each do |pair|
16
+ if pair[:name]
17
+ param_names << pair[:name].to_s
18
+ else
19
+ param_names << "nil"
20
+ end
21
+
22
+ if pair[:identifier]
23
+ param_identifiers << pair[:identifier].to_s
24
+ end
25
+ end
26
+
27
+ block_str += "[" + param_names.select{|p| p}.join(",") + "]"
28
+
29
+ ruby_params_string += param_identifiers.join(",")
30
+ ruby_params_string += "| "
31
+ end
32
+
33
+
34
+ block_str += "){"
35
+
36
+ block_str += ruby_params_string
37
+
38
+ block_str += body.value
39
+ block_str += "}"
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,22 @@
1
+ module Blocktalk
2
+ class CatchNode < Treetop::Runtime::SyntaxNode
3
+ def value
4
+ if self.text_value.match(/catch\: \S+/)
5
+ rescue_str = "rescue #{error_class.identifier.value}"
6
+
7
+ # we have a block parameter
8
+ if catch_block.params.text_value.match(/\|[\s\S]*\|/)
9
+ block_param = catch_block.params.value.first
10
+ rescue_str += " => #{block_param[:identifier]};"
11
+ else
12
+ rescue_str += ";"
13
+ end
14
+
15
+ rescue_str += "#{catch_block.body.value}"
16
+ return rescue_str
17
+ else
18
+ return "rescue;#{catch_block.body.value}"
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,15 @@
1
+ module Blocktalk
2
+ class ClassMethodDefinitionNode < Treetop::Runtime::SyntaxNode
3
+ include ASTHelpers::MethodDefinitions
4
+
5
+ def value
6
+ if method_body.params.respond_to?(:value)
7
+ method_name_with_params = ruby_method(method_name, method_body.params)
8
+ "self.meta_class.class_eval{define_method(:#{method_name_with_params}, &#{method_body.value})}"
9
+ else
10
+ # no parameters given -> simply call define_method with a param-less block
11
+ "self.meta_class.class_eval{define_method(\"#{method_name.value}\", &#{method_body.body.value})}"
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,7 @@
1
+ module Blocktalk
2
+ class CommentNode < Treetop::Runtime::SyntaxNode
3
+ def value
4
+ nil
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module Blocktalk
2
+ class EnsureNode < Treetop::Runtime::SyntaxNode
3
+ def value
4
+ "ensure; #{ensure_block.body.value}"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module Blocktalk
2
+ class ExpressionNode < Treetop::Runtime::SyntaxNode
3
+ def value
4
+ subexpr.elements[0].value
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module Blocktalk
2
+ class IdentifierNode < Treetop::Runtime::SyntaxNode
3
+ def value
4
+ self.text_value
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module Blocktalk
2
+ class IntegerLiteralNode < Treetop::Runtime::SyntaxNode
3
+ def value
4
+ self.text_value.to_i
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module Blocktalk
2
+ class MessageReceiverNode < Treetop::Runtime::SyntaxNode
3
+ def value
4
+ puts "in messagereceivernode"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,8 @@
1
+ module Blocktalk
2
+ class MessageWithParamsNode < Treetop::Runtime::SyntaxNode
3
+ def value
4
+ { :message => message.value,
5
+ :params => params.value}
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,10 @@
1
+ module Blocktalk
2
+ class MessageWithoutParamsNode < Treetop::Runtime::SyntaxNode
3
+ def value
4
+ {
5
+ :message => message.value,
6
+ :params => []
7
+ }
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,31 @@
1
+ module Blocktalk
2
+ class MethodDefinitionNode < Treetop::Runtime::SyntaxNode
3
+ include ASTHelpers::MethodDefinitions
4
+
5
+ def value
6
+ if method_body.params.respond_to?(:value)
7
+ params_val = method_body.params.value
8
+ param_names = params_val.collect{|p| p[:name].to_s[1..-1] if p[:name]}.reject{|p| p.nil?}
9
+
10
+ method_name_val = ruby_method(method_name, method_body.params)
11
+
12
+ eval_str = ""
13
+ # check for constructor definition
14
+ # if we have a method called "initialize_*", we create the
15
+ # initialize method (ruby constructor) and inside call the
16
+ # defined method
17
+ if method_name_val =~ /initialize_\S*/
18
+ eval_str +=
19
+ "define_method(:initialize){|first_val,#{param_names.join(',')}| self.#{method_name_val}(first_val,#{param_names.join(',')})};"
20
+ end
21
+
22
+ # now simply define the method
23
+ eval_str += "define_method(:#{method_name_val}, &#{method_body.value})"
24
+ return eval_str
25
+ else
26
+ # no parameters given -> simply call define_method with a param-less block
27
+ "define_method(:#{method_name.value}){#{method_body.body.value}}"
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,37 @@
1
+ module Blocktalk
2
+ class MethodcallNode < Treetop::Runtime::SyntaxNode
3
+ include ASTHelpers::Methodcalls
4
+ def value
5
+ first_messagecall = ""
6
+
7
+ if looks_like_block?(first_passed_block_with_ws)
8
+ first_messagecall = generate_methodcall(receiver,
9
+ first_message,
10
+ first_passed_block_with_ws.passed_block)
11
+ else
12
+ first_messagecall = generate_methodcall(receiver, first_message)
13
+ end
14
+
15
+ chained_methodcalls = first_messagecall
16
+
17
+ messages.elements.each do |whitespace_with_message|
18
+ ws_w_msg = whitespace_with_message
19
+ chained_methodcalls =
20
+ if looks_like_block?(ws_w_msg.passed_block_with_ws)
21
+ generate_methodcall(chained_methodcalls,
22
+ ws_w_msg.message,
23
+ ws_w_msg.passed_block_with_ws.passed_block)
24
+ else
25
+ generate_methodcall(chained_methodcalls,
26
+ ws_w_msg.message)
27
+ end
28
+ end
29
+
30
+ chained_methodcalls
31
+ end
32
+
33
+ def looks_like_block?(node)
34
+ node.text_value =~ /(\{|do)/
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,28 @@
1
+ module Blocktalk
2
+ class MultipleMethodcallNode < Treetop::Runtime::SyntaxNode
3
+ def value
4
+ eval_str = ""
5
+ receiver_val = receiver.value
6
+ messages.elements.each do |m|
7
+ message_hash = m.message.value
8
+ message = message_hash[:message]
9
+ param_names = message_hash[:params].collect{|p| p.is_a?(Hash) ? p[:name] : nil}
10
+ param_values = message_hash[:params].collect{|p| p.is_a?(Hash) ? p[:value] : p.value}
11
+ message += param_names.join("__")
12
+
13
+ eval_str += "#{receiver_val}.#{message}("
14
+ eval_str += "#{param_values.join(', ')}"
15
+ eval_str += ");"
16
+ end
17
+
18
+ message_hash = final_message.value
19
+ message = message_hash[:message]
20
+ param_names = message_hash[:params].collect{|p| p.is_a?(Hash) ? p[:name] : nil}
21
+ param_values = message_hash[:params].collect{|p| p.is_a?(Hash) ? p[:value] : p.value}
22
+ message += param_names.join("__")
23
+
24
+ eval_str += "#{receiver_val}.#{message}(#{param_values.join(', ')})"
25
+ eval_str
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,8 @@
1
+ module Blocktalk
2
+ class OperatorMessageNode < Treetop::Runtime::SyntaxNode
3
+ def value
4
+ { :message => operator_name.value,
5
+ :params => [param_value]}
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,25 @@
1
+ module Blocktalk
2
+ class RequireNode < Treetop::Runtime::SyntaxNode
3
+ def value
4
+ parser = BlocktalkParser.new
5
+
6
+ file = parse_file.text_value
7
+
8
+ unless file.include?(".bt")
9
+ file += ".bt"
10
+ end
11
+
12
+ file = file.gsub(/\"/, "")
13
+
14
+ $:.each do |path|
15
+ if File.exists?("#{path}/#{file}")
16
+ ast = parser.parse IO.read("#{path}/#{file}")
17
+ ast.evaluate
18
+ return nil # only require once!
19
+ end
20
+ end
21
+
22
+ nil
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,7 @@
1
+ module Blocktalk
2
+ class ReturnNode < Treetop::Runtime::SyntaxNode
3
+ def value
4
+ "return #{ret_val.value}"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,15 @@
1
+ module Blocktalk
2
+ class RootNode < Treetop::Runtime::SyntaxNode
3
+ def evaluate
4
+ self.value
5
+ end
6
+
7
+ def value
8
+ self.exprs.elements.each do |e|
9
+ if e.elements[0].respond_to?(:value)
10
+ Evaluator.add e.elements[0].value
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,7 @@
1
+ module Blocktalk
2
+ class StringLiteralNode < Treetop::Runtime::SyntaxNode
3
+ def value
4
+ "\"" + self.string_val.elements.collect{|e| e.value}.join("") + "\""
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module Blocktalk
2
+ class SubexpressionNode < Treetop::Runtime::SyntaxNode
3
+ def value
4
+ subexpr.value
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,12 @@
1
+ module Blocktalk
2
+ class SuperCallNode < Treetop::Runtime::SyntaxNode
3
+ def value
4
+ params_str = ""
5
+ if params.respond_to?(:value)
6
+ # we've got some params!
7
+ params_str = params.value.collect{|p| p[:value]}.join(",")
8
+ end
9
+ return "super(#{params_str})"
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,7 @@
1
+ module Blocktalk
2
+ class TryNode < Treetop::Runtime::SyntaxNode
3
+ def value
4
+ "begin; #{try_block.body.value}; end;"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,18 @@
1
+ module Blocktalk
2
+ class YieldNode < Treetop::Runtime::SyntaxNode
3
+ def value
4
+ # array_str = yieldval.value
5
+ # array_str = array_str[1..-1]
6
+ # array_str = array_str[0..-2]
7
+
8
+ # yieldparams = []
9
+ # array_str.split(/\s*,\s*/).each do |elem|
10
+ # yieldparams << elem
11
+ # end
12
+ # "yield(#{yieldparams.join(",")})"
13
+
14
+ # not needed, as ArrayLiteralNode returns it correctly for now...
15
+ "yield(#{yieldval.text_value})"
16
+ end
17
+ end
18
+ end
data/parser/nodes.rb ADDED
@@ -0,0 +1,29 @@
1
+ $: << File.expand_path(File.dirname(__FILE__))
2
+
3
+ #require helpers first
4
+ require "helpers/methodcalls"
5
+ require "helpers/method_definitions"
6
+
7
+ require "nodes/block_literal"
8
+ require "nodes/catch"
9
+ require "nodes/class_method_definition"
10
+ require "nodes/comment"
11
+ require "nodes/ensure"
12
+ require "nodes/expression"
13
+ require "nodes/identifier"
14
+ require "nodes/integer_literal"
15
+ require "nodes/message_receiver"
16
+ require "nodes/message_without_params"
17
+ require "nodes/message_with_params"
18
+ require "nodes/methodcall"
19
+ require "nodes/method_definition"
20
+ require "nodes/multiple_methodcall"
21
+ require "nodes/operator_message"
22
+ require "nodes/return"
23
+ require "nodes/require"
24
+ require "nodes/root"
25
+ require "nodes/string"
26
+ require "nodes/subexpression"
27
+ require "nodes/super_call"
28
+ require "nodes/try"
29
+ require "nodes/yield"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bakkdoor-blocktalk
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christopher Bertels
@@ -30,8 +30,75 @@ extensions: []
30
30
 
31
31
  extra_rdoc_files: []
32
32
 
33
- files: []
34
-
33
+ files:
34
+ - README.markdown
35
+ - benchmark.bt
36
+ - TODO
37
+ - LICENSE
38
+ - evaluator.rb
39
+ - grammar/blocktalk.tt
40
+ - grammar/blocktalk.rb
41
+ - lib/core.rb
42
+ - lib/kernel
43
+ - lib/kernel/console.rb
44
+ - lib/kernel/array.rb
45
+ - lib/kernel/error.rb
46
+ - lib/kernel/module.rb
47
+ - lib/kernel/string.rb
48
+ - lib/kernel/class.rb
49
+ - lib/kernel/codeblock.rb
50
+ - lib/kernel/system.rb
51
+ - lib/kernel/object.rb
52
+ - lib/blocktalk
53
+ - lib/blocktalk/string.bt
54
+ - lib/blocktalk/array.bt
55
+ - lib/blocktalk.bt
56
+ - bin/blocktalk
57
+ - examples/test3.bt
58
+ - examples/fac.bt
59
+ - examples/chained_method_call.bt
60
+ - examples/exceptions.bt
61
+ - examples/string_interpol.bt
62
+ - examples/test2.bt
63
+ - examples/ruby_methods.bt
64
+ - examples/multiple_methodcall.bt
65
+ - examples/linecounter.bt
66
+ - examples/require.bt
67
+ - examples/portscan.bt
68
+ - examples/classes_modules.bt
69
+ - examples/test.bt
70
+ - examples/string_test.bt
71
+ - examples/inline_ruby.bt
72
+ - language-spec/blocktalk-lang-spec.bt
73
+ - language-spec/blocktalk-example.bt
74
+ - parser/helpers
75
+ - parser/helpers/method_definitions.rb
76
+ - parser/helpers/methodcalls.rb
77
+ - parser/nodes.rb
78
+ - parser/nodes
79
+ - parser/nodes/message_without_params.rb
80
+ - parser/nodes/block_literal.rb
81
+ - parser/nodes/integer_literal.rb
82
+ - parser/nodes/require.rb
83
+ - parser/nodes/expression.rb
84
+ - parser/nodes/try.rb
85
+ - parser/nodes/comment.rb
86
+ - parser/nodes/multiple_methodcall.rb
87
+ - parser/nodes/root.rb
88
+ - parser/nodes/string.rb
89
+ - parser/nodes/message_receiver.rb
90
+ - parser/nodes/method_definition.rb
91
+ - parser/nodes/subexpression.rb
92
+ - parser/nodes/catch.rb
93
+ - parser/nodes/identifier.rb
94
+ - parser/nodes/ensure.rb
95
+ - parser/nodes/operator_message.rb
96
+ - parser/nodes/return.rb
97
+ - parser/nodes/yield.rb
98
+ - parser/nodes/class_method_definition.rb
99
+ - parser/nodes/super_call.rb
100
+ - parser/nodes/methodcall.rb
101
+ - parser/nodes/message_with_params.rb
35
102
  has_rdoc: false
36
103
  homepage: http://www.adztec-independent.de
37
104
  post_install_message: