fancy 0.4.0 → 0.5.0

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 (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
  }