fancy 0.3.2 → 0.3.3

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 (98) hide show
  1. data/README.md +4 -1
  2. data/Rakefile +8 -0
  3. data/bin/fyi +25 -20
  4. data/bin/ifancy +39 -5
  5. data/{extconf.rb → boot/extconf.rb} +1 -1
  6. data/boot/fancy_ext/block_env.rb +0 -14
  7. data/boot/fancy_ext/kernel.rb +6 -2
  8. data/boot/rbx-compiler/parser/fancy_parser.bundle +0 -0
  9. data/examples/actor.fy +37 -0
  10. data/examples/armstrong_numbers.fy +1 -1
  11. data/examples/curl_async.fy +37 -0
  12. data/examples/echo.fy +1 -1
  13. data/examples/factorial.fy +1 -1
  14. data/examples/future_composition.fy +20 -0
  15. data/examples/game_of_life.fy +2 -2
  16. data/examples/person.fy +4 -8
  17. data/examples/rbx/blocks.fy +1 -1
  18. data/examples/return.fy +1 -1
  19. data/examples/struct.fy +9 -0
  20. data/lib/argv.fy +2 -2
  21. data/lib/array.fy +157 -0
  22. data/lib/block.fy +18 -1
  23. data/lib/boot.fy +5 -1
  24. data/lib/compiler/ast/class_def.fy +1 -1
  25. data/lib/compiler/ast/identifier.fy +2 -2
  26. data/lib/compiler/ast/message_send.fy +2 -2
  27. data/lib/compiler/ast/method_def.fy +2 -2
  28. data/lib/compiler/ast/try_catch.fy +5 -1
  29. data/lib/documentation.fy +1 -1
  30. data/lib/enumerable.fy +3 -7
  31. data/lib/enumerator.fy +77 -0
  32. data/lib/false_class.fy +52 -0
  33. data/lib/fancy_spec.fy +40 -12
  34. data/lib/fdoc.fy +2 -2
  35. data/lib/file.fy +8 -1
  36. data/lib/future.fy +23 -2
  37. data/lib/iteration.fy +60 -0
  38. data/lib/main.fy +4 -4
  39. data/lib/nil_class.fy +14 -22
  40. data/lib/number.fy +51 -0
  41. data/lib/object.fy +126 -43
  42. data/lib/package/installer.fy +1 -1
  43. data/lib/parser/ext/lexer.lex +6 -1
  44. data/lib/parser/ext/parser.y +18 -0
  45. data/lib/parser/methods.fy +20 -2
  46. data/lib/proxy.fy +20 -3
  47. data/lib/rbx.fy +0 -1
  48. data/lib/rbx/array.fy +4 -138
  49. data/lib/rbx/block.fy +25 -1
  50. data/lib/rbx/class.fy +21 -0
  51. data/lib/rbx/exception.fy +1 -0
  52. data/lib/rbx/fiber.fy +1 -0
  53. data/lib/rbx/file.fy +8 -0
  54. data/lib/rbx/integer.fy +0 -8
  55. data/lib/rbx/method.fy +34 -7
  56. data/lib/rbx/no_method_error.fy +8 -1
  57. data/lib/rbx/object.fy +3 -32
  58. data/lib/rbx/range.fy +13 -1
  59. data/lib/rbx/regexp.fy +3 -0
  60. data/lib/rbx/string.fy +6 -1
  61. data/lib/rbx/system.fy +20 -2
  62. data/lib/set.fy +2 -2
  63. data/lib/string.fy +1 -1
  64. data/lib/struct.fy +15 -12
  65. data/lib/symbol.fy +2 -2
  66. data/lib/true_class.fy +16 -20
  67. data/lib/version.fy +1 -1
  68. data/tests/argv.fy +1 -0
  69. data/tests/array.fy +33 -2
  70. data/tests/block.fy +44 -0
  71. data/tests/class.fy +102 -88
  72. data/tests/control_flow.fy +131 -8
  73. data/tests/enumerator.fy +85 -0
  74. data/tests/exception.fy +13 -13
  75. data/tests/file.fy +4 -13
  76. data/tests/future.fy +26 -0
  77. data/tests/method.fy +83 -72
  78. data/tests/nil_class.fy +20 -13
  79. data/tests/number.fy +16 -9
  80. data/tests/object.fy +39 -20
  81. data/tests/string.fy +7 -0
  82. data/tests/true_class.fy +4 -4
  83. data/tools/fancy-mode.el +1 -1
  84. metadata +15 -20
  85. data/boot/compiler/parser/ext/fancy_parser.bundle +0 -0
  86. data/boot/rbx-compiler/parser/Makefile +0 -162
  87. data/boot/rbx-compiler/parser/lexer.c +0 -2316
  88. data/boot/rbx-compiler/parser/lexer.h +0 -315
  89. data/boot/rbx-compiler/parser/parser.c +0 -3105
  90. data/boot/rbx-compiler/parser/parser.h +0 -114
  91. data/lib/lazy_array.fy +0 -23
  92. data/lib/parser/ext/Makefile +0 -162
  93. data/lib/parser/ext/fancy_parser.bundle +0 -0
  94. data/lib/parser/ext/lexer.c +0 -2360
  95. data/lib/parser/ext/lexer.h +0 -315
  96. data/lib/parser/ext/parser.c +0 -3382
  97. data/lib/parser/ext/parser.h +0 -118
  98. data/lib/rbx/false_class.fy +0 -58
data/lib/rbx/exception.fy CHANGED
@@ -1,5 +1,6 @@
1
1
  class StandardError {
2
2
  ruby_alias: 'message
3
+ ruby_alias: 'backtrace
3
4
 
4
5
  def initialize {
5
6
  "Creates a new Exception with an empty message."
data/lib/rbx/fiber.fy CHANGED
@@ -4,6 +4,7 @@ Fiber = Rubinius Fiber
4
4
 
5
5
  class Fiber {
6
6
  metaclass ruby_alias: 'yield
7
+ metaclass ruby_alias: 'current
7
8
  ruby_alias: 'resume
8
9
  ruby_alias: 'alive?
9
10
 
data/lib/rbx/file.fy CHANGED
@@ -174,6 +174,14 @@ class File {
174
174
  print(str)
175
175
  }
176
176
 
177
+ def read: bytes {
178
+ """
179
+ @bytes Integer the amount of bytes to read from a @File@.
180
+ """
181
+
182
+ read(bytes)
183
+ }
184
+
177
185
  def newline {
178
186
  "Writes a newline character to the @File@."
179
187
 
data/lib/rbx/integer.fy CHANGED
@@ -4,12 +4,4 @@ class Integer {
4
4
  def times: block {
5
5
  times(&block)
6
6
  }
7
-
8
- def upto: num do_each: block {
9
- upto(num, &block)
10
- }
11
-
12
- def downto: num do_each: block {
13
- downto(num, &block)
14
- }
15
7
  }
data/lib/rbx/method.fy CHANGED
@@ -1,4 +1,4 @@
1
- class Method {
1
+ class MethodMixin {
2
2
  def documentation {
3
3
  Fancy Documentation for: (executable())
4
4
  }
@@ -6,17 +6,44 @@ class Method {
6
6
  def documentation: str {
7
7
  Fancy Documentation for: (executable()) is: str
8
8
  }
9
- }
10
9
 
11
- class UnboundMethod {
10
+ def visibility {
11
+ """
12
+ Returns the visibility ('private, 'protected, 'public) of a @Method@ in its defined context, if any.
13
+ """
14
+ entry = @defined_in method_table() lookup(@name)
15
+ { entry visibility() } if: entry
16
+ }
12
17
 
13
- def documentation {
14
- Fancy Documentation for: (executable())
18
+ def public? {
19
+ """
20
+ Returns true, if the @Method@ is public in its defined context.
21
+ """
22
+ visibility == 'public
15
23
  }
16
24
 
17
- def documentation: str {
18
- Fancy Documentation for: (executable()) is: str
25
+ def protected? {
26
+ """
27
+ Returns true, if the @Method@ is protected in its defined context.
28
+ """
29
+ visibility == 'protected
19
30
  }
20
31
 
32
+ def private? {
33
+ """
34
+ Returns true, if the @Method@ is private in its defined context.
35
+ """
36
+ visibility == 'private
37
+ }
38
+ }
39
+
40
+ class Method {
41
+ ruby_alias: 'arity
42
+ include: MethodMixin
43
+ }
44
+
45
+ class UnboundMethod {
46
+ ruby_alias: 'arity
47
+ include: MethodMixin
21
48
  }
22
49
 
@@ -10,6 +10,13 @@ class NoMethodError {
10
10
  Returns the name of the method that was not found as a @String@.
11
11
  """
12
12
 
13
- name to_s from: 1 to: -1
13
+ match name to_s {
14
+ case /^:/ -> name to_s from: 1 to: -1 . to_sym
15
+ case _ -> name
16
+ }
17
+ }
18
+
19
+ def self inspect {
20
+ "NoMethodError"
14
21
  }
15
22
  }
data/lib/rbx/object.fy CHANGED
@@ -40,35 +40,6 @@ class Object {
40
40
  instance_variable_get("@" ++ slotname)
41
41
  }
42
42
 
43
- def and: other {
44
- """
45
- Boolean conjunction.
46
- Returns true if self and other are true, otherwise nil.
47
- """
48
-
49
- self if_do: {
50
- other if_do: {
51
- return true
52
- }
53
- }
54
- return false
55
- }
56
-
57
- def or: other {
58
- """
59
- Boolean disjunction.
60
- Returns true if either self or other is true, otherwise nil.
61
- """
62
- self if_do: {
63
- return true
64
- } else: {
65
- other if_do: {
66
- return true
67
- }
68
- }
69
- return false
70
- }
71
-
72
43
  def define_singleton_method: name with: block {
73
44
  metaclass define_method: name with: block
74
45
  }
@@ -87,17 +58,17 @@ class Object {
87
58
  kind_of?(class)
88
59
  }
89
60
 
90
- def send: message {
61
+ def send_message: message {
91
62
  send(message_name: message)
92
63
  }
93
64
 
94
- def send: message params: params {
65
+ def send_message: message with_params: params {
95
66
  ruby: (message_name: message) args: params
96
67
  }
97
68
 
98
69
  def message_name: symbol {
99
70
  symbol = symbol to_s
100
- if: (symbol includes?: ":") then: {
71
+ if: (symbol =~ /:/) then: {
101
72
  symbol
102
73
  } else: {
103
74
  ":" ++ symbol
data/lib/rbx/range.fy CHANGED
@@ -10,6 +10,18 @@ class Range {
10
10
  }
11
11
 
12
12
  def each: block {
13
- each(&block)
13
+ try {
14
+ val = nil
15
+ each() |x| {
16
+ try {
17
+ val = block call: [x]
18
+ } catch (Fancy NextIteration) => ex {
19
+ val = ex return_value
20
+ }
21
+ }
22
+ val
23
+ } catch (Fancy BreakIteration) => ex {
24
+ ex return_value
25
+ }
14
26
  }
15
27
  }
data/lib/rbx/regexp.fy CHANGED
@@ -1,4 +1,7 @@
1
1
  class Regexp {
2
+ ruby_alias: 'inspect
3
+ ruby_alias: 'to_s
4
+
2
5
  def === string {
3
6
  ruby: 'match args: [string]
4
7
  }
data/lib/rbx/string.fy CHANGED
@@ -9,6 +9,7 @@ class String {
9
9
  ruby_alias: 'to_f
10
10
  ruby_alias: 'chomp
11
11
  ruby_alias: 'inspect
12
+ ruby_alias: 'to_sym
12
13
 
13
14
  def [] index {
14
15
  """Given an Array of 2 Numbers, it returns the substring between the given indices.
@@ -39,7 +40,7 @@ class String {
39
40
 
40
41
  Calls a given @Block with each character in a @String.
41
42
  """
42
- split("") each(&block)
43
+ split("") each: block
43
44
  }
44
45
 
45
46
  def at: idx {
@@ -98,4 +99,8 @@ class String {
98
99
  def % values {
99
100
  ruby: '% args: [values to_a]
100
101
  }
102
+
103
+ def unpack: format {
104
+ unpack(format)
105
+ }
101
106
  }
data/lib/rbx/system.fy CHANGED
@@ -1,3 +1,5 @@
1
+ require("open3")
2
+
1
3
  class System {
2
4
  def System exit {
3
5
  "Exit the running Fancy process."
@@ -22,10 +24,26 @@ class System {
22
24
 
23
25
  def System pipe: command_str {
24
26
  """
25
- Runs the given string as a popen() call and returns a IO handle
27
+ @command_str String to run as a command via popen3()
28
+ @return @IO@ object representing the command's @STDOUT IO stream.
29
+
30
+ Runs the given string as a popen3() call and returns a IO handle
26
31
  that can be read from
27
32
  """
28
33
 
29
- IO popen(command_str)
34
+ in, out, err = Open3 popen3(command_str)
35
+ return out
36
+ }
37
+
38
+ def System pipe: command_str do: block {
39
+ """
40
+ @command_str String to run as a command via popen3()
41
+ @block @Block@ to be called with @STDIN, @STDOUT and @STDERR.
42
+
43
+ Runs the given string as a popen3() call, passing in a given @Block@.
44
+ The @Block@ is expected to take 3 arguments for @STDIN, @STDOUT and @STDERR.
45
+ """
46
+
47
+ Open3 popen3(command_str, &block)
30
48
  }
31
49
  }
data/lib/set.fy CHANGED
@@ -43,9 +43,9 @@ class Set {
43
43
 
44
44
  def unknown_message: msg with_params: params {
45
45
  if: (params empty?) then: {
46
- @values send: msg
46
+ @values send_message: msg
47
47
  } else: {
48
- @values send: msg params: params
48
+ @values send_message: msg with_params: params
49
49
  }
50
50
  }
51
51
 
data/lib/string.fy CHANGED
@@ -25,7 +25,7 @@ class String {
25
25
  def blank? {
26
26
  "Indicates, if a String consists only of whitespace."
27
27
 
28
- self =~ /^\s*$/ if_do: {
28
+ self =~ /^\s*$/ if_true: {
29
29
  true
30
30
  } else: {
31
31
  false
data/lib/struct.fy CHANGED
@@ -1,13 +1,16 @@
1
1
  class Struct {
2
- def Struct new: fields {
3
- struct = ruby: "new" args: fields
4
- struct read_write_slots: fields
5
- struct define_method: "new:" with: |values| {
6
- instance = struct new()
7
- fields each_with_index: |f i| {
8
- instance send: f params: [values at: i]
9
- }
10
- }
11
- struct
12
- }
13
- }
2
+ def Struct new: fields {
3
+ struct = new(*fields)
4
+ struct read_write_slots: fields
5
+
6
+ def struct new: values {
7
+ new(*values)
8
+ }
9
+
10
+ def struct new {
11
+ new()
12
+ }
13
+
14
+ struct
15
+ }
16
+ }
data/lib/symbol.fy CHANGED
@@ -14,9 +14,9 @@ class Symbol {
14
14
  """
15
15
 
16
16
  if: (arg is_a?: Array) then: {
17
- arg first send: self params: $ arg rest
17
+ arg first send_message: self with_params: $ arg rest
18
18
  } else: {
19
- arg send: self
19
+ arg send_message: self
20
20
  }
21
21
  }
22
22
 
data/lib/true_class.fy CHANGED
@@ -1,5 +1,5 @@
1
1
  class TrueClass {
2
- "TrueClass. The class of the singleton true value."
2
+ "TrueClass. The class of the singleton @true value."
3
3
 
4
4
  def TrueClass new {
5
5
  # always return true singleton object when trying to create a new
@@ -7,37 +7,33 @@ class TrueClass {
7
7
  true
8
8
  }
9
9
 
10
- def if_true: then_block else: else_block {
11
- "Calls the then_block."
12
- then_block call
13
- }
14
-
15
10
  def if_true: block {
16
- "Calls the block."
17
- block call
11
+ "Calls @block."
12
+ block call: [self]
18
13
  }
19
14
 
20
- def if_false: block {
21
- "Returns nil."
22
- nil
15
+ def if_true: then_block else: else_block {
16
+ "Calls @then_block."
17
+ then_block call: [self]
23
18
  }
24
19
 
25
- def nil? {
26
- "Returns nil."
27
- false
20
+ def true? {
21
+ "Returns @true."
22
+ true
28
23
  }
29
24
 
30
- def false? {
31
- "Returns nil."
32
- false
25
+ def to_s {
26
+ "Returns @true as a @String@."
27
+ "true"
33
28
  }
34
29
 
35
- def true? {
36
- "Returns true."
37
- true
30
+ def to_a {
31
+ "Returns an empty @Array@."
32
+ []
38
33
  }
39
34
 
40
35
  def not {
36
+ "Returns @false."
41
37
  false
42
38
  }
43
39
  }
data/lib/version.fy CHANGED
@@ -1,6 +1,6 @@
1
1
  VERSION_MAJOR = 0
2
2
  VERSION_MINOR = 3
3
- VERSION_PATCH = 0
3
+ VERSION_PATCH = 3
4
4
  VERSION_SUFFIX = "alpha"
5
5
 
6
6
  FANCY_VERSION = [VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH] join: "." ++ " " ++ VERSION_SUFFIX
data/tests/argv.fy CHANGED
@@ -5,6 +5,7 @@ FancySpec describe: "ARGV & predefined values" with: {
5
5
 
6
6
  it: "should have a __FILE__ variable defined" when: {
7
7
  __FILE__ should_not == nil
8
+ __FILE__ should =~ /\/argv.fy$/
8
9
  }
9
10
 
10
11
  it: "should have the __FILE__ value be an element in ARGV" when: {
data/tests/array.fy CHANGED
@@ -10,8 +10,7 @@ FancySpec describe: Array with: {
10
10
 
11
11
  it: "should iterate over all elements, calling a block" for: 'each: when: {
12
12
  sum = 0
13
- retval = [1,2,3,4,5] each: |x| { sum = sum + x }
14
- retval should == sum
13
+ [1,2,3,4,5] each: |x| { sum = sum + x }
15
14
  sum should == ([1,2,3,4,5] sum)
16
15
  }
17
16
 
@@ -43,6 +42,18 @@ FancySpec describe: Array with: {
43
42
  arr at: 0 . should == 'a
44
43
  }
45
44
 
45
+ it: "should set the value for a given index" for: 'at:put: when: {
46
+ arr = [1,2,3]
47
+ arr at: 0 put: 10
48
+ arr should == [10, 2, 3]
49
+ arr at: -1 put: 30
50
+ arr should == [10, 2, 30]
51
+ arr at: 1 put: 20
52
+ arr should == [10,20,30]
53
+ arr at: 3 put: 40
54
+ arr should == [10,20,30,40]
55
+ }
56
+
46
57
  it: "should NOT include the items" for: "includes?:" when: {
47
58
  arr = ['a, 10, "hello, world"]
48
59
  arr includes?: "hello" . should == false
@@ -340,4 +351,24 @@ FancySpec describe: Array with: {
340
351
  arr partition_by: 'identity . should == [[1], [2,2], [3,3,3], [4,4,4,4], [5]]
341
352
  arr partition_by: @{== 2} . should == [[1], [2,2], [3,3,3,4,4,4,4,5]]
342
353
  }
354
+
355
+ it: "should remove the first value" for: 'shift when: {
356
+ a = [1,2,3]
357
+ a shift should == 1
358
+ a should == [2,3]
359
+
360
+ a = []
361
+ a shift should == nil
362
+ a should == []
363
+ }
364
+
365
+ it: "should append a value at the front" for: 'unshift: when: {
366
+ a = []
367
+ a unshift: 1 . should == a # should return self
368
+ a should == [1]
369
+
370
+ a = [1,2,3]
371
+ a unshift: (a shift) . should == a
372
+ a should == [1,2,3]
373
+ }
343
374
  }