fancy 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (94) hide show
  1. data/README.md +1 -0
  2. data/bin/fspec +3 -1
  3. data/boot/code_loader.rb +5 -1
  4. data/boot/compiler/parser/ext/fancy_parser.bundle +0 -0
  5. data/boot/fancy_ext.rb +2 -0
  6. data/boot/fancy_ext/bootstrap.rb +6 -0
  7. data/boot/fancy_ext/symbol.rb +9 -0
  8. data/boot/fancy_ext/thread.rb +22 -1
  9. data/boot/load.rb +1 -0
  10. data/boot/rbx-compiler/parser/Makefile +156 -0
  11. data/boot/rbx-compiler/parser/fancy_parser.bundle +0 -0
  12. data/boot/rbx-compiler/parser/lexer.c +2310 -0
  13. data/boot/rbx-compiler/parser/lexer.h +315 -0
  14. data/boot/rbx-compiler/parser/parser.c +2946 -0
  15. data/boot/rbx-compiler/parser/parser.h +151 -0
  16. data/doc/api/fancy.jsonp +1 -1
  17. data/doc/features.md +8 -0
  18. data/examples/actors.fy +5 -9
  19. data/examples/actors_primitive.fy +4 -3
  20. data/examples/actors_ring.fy +15 -14
  21. data/examples/dynamic.fy +8 -0
  22. data/examples/dynamic_output.fy +15 -0
  23. data/examples/parsing.fy +1 -0
  24. data/examples/person.fy +1 -2
  25. data/lib/array.fy +49 -11
  26. data/lib/block.fy +18 -24
  27. data/lib/boot.fy +1 -1
  28. data/lib/class.fy +6 -6
  29. data/lib/compiler/ast.fy +0 -1
  30. data/lib/compiler/ast/assign.fy +25 -0
  31. data/lib/compiler/ast/block.fy +1 -0
  32. data/lib/compiler/ast/identifier.fy +16 -0
  33. data/lib/compiler/ast/literals.fy +4 -0
  34. data/lib/compiler/ast/message_send.fy +16 -1
  35. data/lib/enumerable.fy +45 -18
  36. data/lib/enumerator.fy +15 -15
  37. data/lib/false_class.fy +8 -0
  38. data/lib/fancy_spec.fy +20 -20
  39. data/lib/future.fy +35 -18
  40. data/lib/hash.fy +2 -2
  41. data/lib/integer.fy +1 -17
  42. data/lib/iteration.fy +36 -36
  43. data/lib/object.fy +65 -30
  44. data/lib/package.fy +2 -2
  45. data/lib/package/installer.fy +6 -0
  46. data/lib/parser/ext/Makefile +156 -0
  47. data/lib/parser/ext/fancy_parser.bundle +0 -0
  48. data/lib/parser/ext/lexer.c +2392 -0
  49. data/lib/parser/ext/lexer.h +315 -0
  50. data/lib/parser/ext/lexer.lex +0 -10
  51. data/lib/parser/ext/parser.c +3251 -0
  52. data/lib/parser/ext/parser.h +161 -0
  53. data/lib/parser/ext/parser.y +0 -22
  54. data/lib/parser/methods.fy +1 -13
  55. data/lib/range.fy +3 -3
  56. data/lib/rbx.fy +1 -0
  57. data/lib/rbx/actor.fy +4 -4
  58. data/lib/rbx/alpha.fy +6 -0
  59. data/lib/rbx/array.fy +5 -44
  60. data/lib/rbx/bignum.fy +1 -12
  61. data/lib/rbx/block.fy +25 -0
  62. data/lib/rbx/class.fy +1 -7
  63. data/lib/rbx/date.fy +1 -5
  64. data/lib/rbx/file.fy +1 -4
  65. data/lib/rbx/fixnum.fy +4 -16
  66. data/lib/rbx/float.fy +1 -10
  67. data/lib/rbx/integer.fy +14 -2
  68. data/lib/rbx/io.fy +1 -5
  69. data/lib/rbx/mutex.fy +30 -0
  70. data/lib/rbx/object.fy +5 -11
  71. data/lib/rbx/process.fy +13 -0
  72. data/lib/rbx/range.fy +1 -5
  73. data/lib/rbx/string.fy +4 -11
  74. data/lib/rbx/thread.fy +9 -0
  75. data/lib/rbx/time.fy +1 -7
  76. data/lib/stack.fy +1 -1
  77. data/lib/string.fy +9 -9
  78. data/lib/symbol.fy +12 -7
  79. data/lib/tuple.fy +18 -3
  80. data/lib/vars.fy +3 -0
  81. data/ruby_lib/fspec +2 -2
  82. data/ruby_lib/fyi +2 -2
  83. data/ruby_lib/ifancy +2 -2
  84. data/tests/array.fy +25 -1
  85. data/tests/assignment.fy +55 -0
  86. data/tests/future.fy +28 -0
  87. data/tests/set.fy +20 -0
  88. data/tests/stack.fy +46 -0
  89. data/tests/string.fy +1 -1
  90. data/tests/tuple.fy +22 -0
  91. data/tools/fancy-mode.el +1 -1
  92. metadata +26 -8
  93. data/lib/compiler/ast/goto.fy +0 -46
  94. data/lib/message.fy +0 -6
data/lib/rbx/fixnum.fy CHANGED
@@ -7,22 +7,10 @@ class Fixnum {
7
7
 
8
8
  include: Number
9
9
 
10
- ruby_alias: '==
11
- ruby_alias: '-
12
- ruby_alias: '+
13
- ruby_alias: '*
14
- ruby_alias: '/
15
- ruby_alias: '<
16
- ruby_alias: '>
17
- ruby_alias: '<=
18
- ruby_alias: '>=
19
- ruby_alias: '===
20
- ruby_alias: 'chr
21
- ruby_alias: 'to_i
22
- ruby_alias: 'to_f
23
- ruby_alias: '**
24
- ruby_alias: '&
25
- ruby_alias: '|
10
+ ruby_aliases: [
11
+ '==, '-, '+, '*, '/, '<, '>, '<=, '>=,
12
+ '===, 'chr, 'to_i, 'to_f, '**, '&, '|
13
+ ]
26
14
 
27
15
  alias_method: 'to_s: for: 'to_s
28
16
  alias_method: 'modulo: for: 'modulo
data/lib/rbx/float.fy CHANGED
@@ -7,16 +7,7 @@ class Float {
7
7
 
8
8
  forwards_unary_ruby_methods
9
9
 
10
- ruby_alias: '+
11
- ruby_alias: '-
12
- ruby_alias: '*
13
- ruby_alias: '/
14
- ruby_alias: '==
15
- ruby_alias: '>=
16
- ruby_alias: '<=
17
- ruby_alias: '**
18
- ruby_alias: '<
19
- ruby_alias: '>
10
+ ruby_aliases: [ '+, '-, '*, '/, '==, '<, '>, '<=, '>=, '**]
20
11
 
21
12
  alias_method: 'modulo: for: 'modulo
22
13
  alias_method: ":%" for: "modulo:" # use a : so we dont overwrite ruby's % operator
data/lib/rbx/integer.fy CHANGED
@@ -2,7 +2,19 @@ class Integer {
2
2
  # common ruby-forwarding methods used by Fixnum & Bignum classes
3
3
 
4
4
  def times: block {
5
- # this version gets replaced in lib/integer.fy with a native one
6
- times(&block)
5
+ """
6
+ @block @Block@ to be called with each number between 0 and @self.
7
+ @return @self
8
+
9
+ Calls a given @Block@ with each number between 0 and @self.
10
+ """
11
+
12
+ try {
13
+ times(&block)
14
+ } catch Fancy BreakIteration => b {
15
+ return b result
16
+ } catch Fancy StopIteration => s {
17
+ return s result
18
+ }
7
19
  }
8
20
  }
data/lib/rbx/io.fy CHANGED
@@ -30,11 +30,7 @@ class IO {
30
30
 
31
31
  include: IOMixin
32
32
 
33
- ruby_alias: 'readlines
34
- ruby_alias: 'readline
35
- ruby_alias: 'read
36
- ruby_alias: 'close
37
- ruby_alias: 'eof?
33
+ ruby_aliases: [ 'readlines, 'readline, 'read, 'close, 'eof? ]
38
34
 
39
35
  forwards_unary_ruby_methods
40
36
  }
data/lib/rbx/mutex.fy ADDED
@@ -0,0 +1,30 @@
1
+ class Mutex {
2
+ forwards_unary_ruby_methods
3
+
4
+ def initialize {
5
+ initialize()
6
+ }
7
+
8
+ def synchronize: block {
9
+ synchronize(&block)
10
+ }
11
+ }
12
+
13
+ class ConditionVariable {
14
+ forwards_unary_ruby_methods
15
+ def initialize {
16
+ initialize()
17
+ }
18
+
19
+ def wait: mutex {
20
+ wait(mutex)
21
+ }
22
+
23
+ def signal {
24
+ signal()
25
+ }
26
+
27
+ def broadcast {
28
+ broadcast()
29
+ }
30
+ }
data/lib/rbx/object.fy CHANGED
@@ -1,10 +1,5 @@
1
1
  class Object {
2
- ruby_alias: '==
3
- ruby_alias: '===
4
- ruby_alias: 'class
5
- ruby_alias: 'inspect
6
- ruby_alias: 'object_id
7
- ruby_alias: 'instance_variables
2
+ ruby_aliases: [ '==, '===, 'class, 'inspect, 'object_id, 'instance_variables ]
8
3
 
9
4
  def initialize {
10
5
  initialize()
@@ -118,11 +113,10 @@ class Object {
118
113
 
119
114
  def message_name: symbol {
120
115
  symbol = symbol to_s
121
- match symbol =~ /:/ {
122
- case nil ->
123
- ":" ++ symbol
124
- case _ ->
125
- symbol
116
+ val = symbol include?(":")
117
+ match val {
118
+ case true -> symbol
119
+ case false -> ":" <<(symbol)
126
120
  }
127
121
  }
128
122
 
@@ -0,0 +1,13 @@
1
+ RbxProcess = Process
2
+
3
+ class send('remove_const, 'Process)
4
+
5
+ class Process {
6
+ include: RbxProcess
7
+ metaclass include: (RbxProcess metaclass)
8
+ forwards_unary_ruby_methods
9
+ metaclass forwards_unary_ruby_methods
10
+ }
11
+
12
+ Process pid println
13
+ Process instance_methods sort println
data/lib/rbx/range.fy CHANGED
@@ -1,9 +1,5 @@
1
1
  class Range {
2
- ruby_alias: 'to_a
3
- ruby_alias: '==
4
- ruby_alias: '===
5
- ruby_alias: 'first
6
- ruby_alias: 'last
2
+ ruby_aliases: [ 'to_a, '==, '===, 'first, 'last ]
7
3
 
8
4
  def initialize: @start to: @end {
9
5
  """
data/lib/rbx/string.fy CHANGED
@@ -1,17 +1,10 @@
1
1
  class String {
2
2
 
3
3
  # prepend a : to fancy version of ruby methods.
4
- ruby_alias: '==
5
- ruby_alias: 'upcase
6
- ruby_alias: 'downcase
7
- ruby_alias: '=~
8
- ruby_alias: 'to_i
9
- ruby_alias: 'to_f
10
- ruby_alias: 'chomp
11
- ruby_alias: 'inspect
12
- ruby_alias: 'to_sym
13
- ruby_alias: '<
14
- ruby_alias: '>
4
+ ruby_aliases: [
5
+ '==, 'upcase, 'downcase, '=~, 'to_i, 'to_f,
6
+ 'chomp, 'inspect, 'to_sym, '<, '>
7
+ ]
15
8
 
16
9
  alias_method: '[]: for_ruby: '[]=
17
10
  alias_method: 'scan: for_ruby: 'scan
data/lib/rbx/thread.fy CHANGED
@@ -35,6 +35,15 @@ class Thread {
35
35
  Thread metaclass ruby_alias: 'main
36
36
  Thread metaclass ruby_alias: 'pass
37
37
  Thread metaclass ruby_alias: 'stop
38
+ ruby_alias: 'dynamic_vars
39
+
40
+ def [dynamic_var_name] {
41
+ send('[], dynamic_var_name)
42
+ }
43
+
44
+ def [dynamic_var_name]: value {
45
+ send('[]=, dynamic_var_name, value)
46
+ }
38
47
 
39
48
  def priority: new_prio {
40
49
  priority=(new_prio)
data/lib/rbx/time.fy CHANGED
@@ -6,13 +6,7 @@ class Time {
6
6
  forwards_unary_ruby_methods
7
7
 
8
8
  metaclass ruby_alias: 'now
9
- ruby_alias: '==
10
- ruby_alias: '-
11
- ruby_alias: '+
12
- ruby_alias: '>
13
- ruby_alias: '<
14
- ruby_alias: '>=
15
- ruby_alias: '<=
9
+ ruby_aliases: [ '==, '-, '+, '<, '>, '<=, '>= ]
16
10
 
17
11
  def != other {
18
12
  self == other not
data/lib/stack.fy CHANGED
@@ -77,6 +77,6 @@ class Stack {
77
77
  Calls a given @Block@ with each element in @self, starting with the top of stack element.
78
78
  """
79
79
 
80
- @arr reverse each: block
80
+ @arr reverse_each: block
81
81
  }
82
82
  }
data/lib/string.fy CHANGED
@@ -16,7 +16,7 @@ class String {
16
16
  @return Concatenation of @self with @other.
17
17
 
18
18
  Concatenate @self with another Object's @String@ representation.
19
- \"foo\” ++ 42 # => \”foo42\”
19
+ \"foo\” ++ 42 # => \”foo42\”
20
20
  """
21
21
 
22
22
  self + (other to_s)
@@ -52,7 +52,7 @@ class String {
52
52
  @return @String@ that is the num-fold concatenation of @self.
53
53
 
54
54
  Returns a @String@ that is the num-fold concatenation of itself.
55
- \"foo\" * 3 # => \”foofoofoo\"
55
+ \"foo\" * 3 # => \”foofoofoo\"
56
56
  """
57
57
 
58
58
  str = ""
@@ -66,7 +66,7 @@ class String {
66
66
  """
67
67
  @return @Array@ of all the whitespace seperated words in @self.
68
68
 
69
- \"hello world\" words # => [\"hello\", \"world\"]
69
+ \"hello world\" words # => [\"hello\", \"world\"]
70
70
  """
71
71
 
72
72
  split
@@ -85,7 +85,7 @@ class String {
85
85
  @return @String@ containing all but the first character.
86
86
 
87
87
  Returns a @String@ containing all but the first character.
88
- \"hello\" rest # => \"ello\"
88
+ \"hello\" rest # => \"ello\"
89
89
  """
90
90
 
91
91
  from: 1 to: -1
@@ -108,11 +108,11 @@ class String {
108
108
 
109
109
  Appends @object's @String@ representation to @self.
110
110
 
111
- Example usage:
112
- str = \"hello\"
113
- str << \" \"
114
- str << 42
115
- str # => \"hello 42\"
111
+ Example:
112
+ str = \"hello\"
113
+ str << \" \"
114
+ str << 42
115
+ str # => \"hello 42\"
116
116
  """
117
117
 
118
118
  append: $ object to_s
data/lib/symbol.fy CHANGED
@@ -10,7 +10,8 @@ class Symbol {
10
10
  """
11
11
  This allows Symbols to be used like Blocks
12
12
  (e.g. in all methods of Enumerable).
13
- Example: [1, 2, 3] map: 'squared # => [1, 4, 9]
13
+ Example:
14
+ [1, 2, 3] map: 'squared # => [1, 4, 9]
14
15
  """
15
16
 
16
17
  if: (arg is_a?: Array) then: {
@@ -24,13 +25,13 @@ class Symbol {
24
25
  """
25
26
  Sends @self as message to the sender in its context.
26
27
  Example:
27
- 'foo call
28
- # => same as
29
- self foo
28
+ 'foo call
29
+ # => same as
30
+ self foo
30
31
 
31
- if: x then: 'foo else: 'bar
32
- # same as:
33
- if: x then: { self foo } else: { self bar }
32
+ if: x then: 'foo else: 'bar
33
+ # same as:
34
+ if: x then: { self foo } else: { self bar }
34
35
  """
35
36
 
36
37
  binding = Binding setup(Rubinius VariableScope of_sender(),
@@ -39,4 +40,8 @@ class Symbol {
39
40
  recv = binding self()
40
41
  recv receive_message: self
41
42
  }
43
+
44
+ def arity {
45
+ 1
46
+ }
42
47
  }
data/lib/tuple.fy CHANGED
@@ -54,11 +54,26 @@ class Tuple {
54
54
  Calls a given @Block@ with each element in the @Tuple@.
55
55
  """
56
56
 
57
- val = nil
58
57
  size times: |i| {
59
- val = block call: [at: i]
58
+ block call: [at: i]
60
59
  }
61
- val
60
+ self
61
+ }
62
+
63
+ def reverse_each: block {
64
+ """
65
+ @block @Block@ to be called for each element (in reverse order).
66
+ @return @self.
67
+
68
+ Example:
69
+ (1,2,3) reverse_each: @{print}
70
+ # prints: 321
71
+ """
72
+
73
+ size - 1 downto: 0 do: |i| {
74
+ block call: [at: i]
75
+ }
76
+ self
62
77
  }
63
78
 
64
79
  def == other {
data/lib/vars.fy ADDED
@@ -0,0 +1,3 @@
1
+ *stdin* = STDIN
2
+ *stdout* = STDOUT
3
+ *stderr* = STDERR
data/ruby_lib/fspec CHANGED
@@ -1,3 +1,3 @@
1
- #!/usr/bin/env rbx
1
+ #!/usr/bin/env ruby
2
2
  base = File.expand_path("../bin", File.dirname(__FILE__))
3
- system("/usr/bin/env fancy #{base}/fspec #{ARGV.join(' ')}")
3
+ system("/usr/bin/env fancy #{base}/fspec #{ARGV.join(' ')}")
data/ruby_lib/fyi CHANGED
@@ -1,3 +1,3 @@
1
- #!/usr/bin/env rbx
1
+ #!/usr/bin/env ruby
2
2
  base = File.expand_path("../bin", File.dirname(__FILE__))
3
- system("/usr/bin/env fancy #{base}/fyi #{ARGV.join(' ')}")
3
+ system("/usr/bin/env fancy #{base}/fyi #{ARGV.join(' ')}")
data/ruby_lib/ifancy CHANGED
@@ -1,3 +1,3 @@
1
- #!/usr/bin/env rbx
1
+ #!/usr/bin/env ruby
2
2
  base = File.expand_path("../bin", File.dirname(__FILE__))
3
- system("/usr/bin/env fancy #{base}/ifancy #{ARGV.join(' ')}")
3
+ system("/usr/bin/env fancy #{base}/ifancy #{ARGV.join(' ')}")
data/tests/array.fy CHANGED
@@ -388,7 +388,31 @@ FancySpec describe: Array with: {
388
388
  a is: []
389
389
  }
390
390
 
391
- it: "appends a value at the front" with: 'unshift: when: {
391
+ it: "appends another Array onto self" with: 'append: when: {
392
+ a = [1,2,3]
393
+ a append: [4,5,6] . is: a
394
+ a is: [1,2,3,4,5,6]
395
+
396
+ a append: []
397
+ a is: [1,2,3,4,5,6]
398
+
399
+ [] append: [] . is: []
400
+ [] append: (1,2,3) . is: [1,2,3] # works with any Enumerable
401
+ }
402
+
403
+ it: "prepends another Array onto self" with: 'prepend: when: {
404
+ a = [1,2,3]
405
+ a prepend: [4,5,6]
406
+ a is: [4,5,6,1,2,3]
407
+
408
+ a prepend: []
409
+ a is: [4,5,6,1,2,3]
410
+
411
+ [] prepend: [] . is: []
412
+ [] prepend: (1,2,3) . is: [1,2,3] # works with any Enumerable
413
+ }
414
+
415
+ it: "prepends a value at the front" with: 'unshift: when: {
392
416
  a = []
393
417
  a unshift: 1 . is: a # is return self
394
418
  a is: [1]
data/tests/assignment.fy CHANGED
@@ -50,4 +50,59 @@ FancySpec describe: "Assignment" with: {
50
50
  _,_,*z = "hello, world!" # ignore first 2 characters
51
51
  z is: "llo, world!"
52
52
  }
53
+
54
+ it: "sets dynamic vars accordingly" when: {
55
+ let: '*foo* be: 10 in: {
56
+ *foo* is: 10
57
+ }
58
+ }
59
+
60
+ it: "sets a dynamic var with proper nesting" when: {
61
+ def use_foo: expected {
62
+ *foo* is: expected
63
+ }
64
+
65
+ def use_nested_foo: expected {
66
+ use_foo: expected
67
+ let: '*foo* be: -10 in: {
68
+ use_foo: -10
69
+ }
70
+ }
71
+
72
+ let: '*foo* be: 10 in: {
73
+ *foo* is: 10
74
+ use_foo: 10
75
+ use_nested_foo: 10
76
+ let: '*foo* be: 100 in: {
77
+ *foo* is: 100
78
+ use_foo: 100
79
+ use_nested_foo: 100
80
+ }
81
+ }
82
+ }
83
+
84
+ it: "allows assigning dynamic vars without a scope" when: {
85
+ *foo* = "hello, world"
86
+ *foo* is: "hello, world"
87
+ let: '*foo* be: "byebye, world" in: {
88
+ *foo* is: "byebye, world"
89
+ use_foo: "byebye, world"
90
+ use_nested_foo: "byebye, world"
91
+ }
92
+ *foo* is: "hello, world"
93
+ use_foo: "hello, world"
94
+ use_nested_foo: "hello, world"
95
+ *foo* = nil
96
+ *foo* is: nil
97
+ use_foo: nil
98
+ use_nested_foo: nil
99
+ }
100
+
101
+ it: "preserves the current value of a dynvar when creating a new thread" when: {
102
+ *foo* = 100
103
+ *foo* is: 100
104
+ Thread new: {
105
+ *foo* is: 100
106
+ } . join
107
+ }
53
108
  }