fancy 0.3.0 → 0.3.1

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 (113) hide show
  1. data/{README → README.md} +33 -50
  2. data/Rakefile +6 -1
  3. data/bin/fyi +13 -10
  4. data/boot/fancy_ext.rb +1 -0
  5. data/boot/fancy_ext/block_env.rb +6 -2
  6. data/boot/fancy_ext/console.rb +4 -0
  7. data/boot/fancy_ext/object.rb +6 -0
  8. data/boot/rbx-compiler/compiler/ast/identifier.rb +5 -1
  9. data/boot/rbx-compiler/compiler/ast/match.rb +4 -5
  10. data/boot/rbx-compiler/compiler/ast/super.rb +1 -0
  11. data/boot/rbx-compiler/parser/fancy_parser.bundle +0 -0
  12. data/boot/rbx-compiler/parser/lexer.c +2316 -0
  13. data/boot/rbx-compiler/parser/lexer.h +315 -0
  14. data/boot/rbx-compiler/parser/parser.c +3105 -0
  15. data/boot/rbx-compiler/parser/parser.h +114 -0
  16. data/boot/rbx-compiler/parser/parser.rb +2 -2
  17. data/boot/rbx-compiler/parser/parser.y +3 -3
  18. data/doc/api/fancy.jsonp +1 -1
  19. data/doc/features.md +14 -3
  20. data/examples/async_send.fy +11 -0
  21. data/examples/fibonacci.fy +1 -1
  22. data/examples/future.fy +30 -0
  23. data/examples/futures.fy +14 -0
  24. data/examples/game_of_life.fy +1 -1
  25. data/examples/matchers.fy +1 -1
  26. data/examples/pattern_matching.fy +3 -3
  27. data/examples/stupid_quicksort.fy +1 -1
  28. data/examples/threads.fy +1 -1
  29. data/extconf.rb +7 -0
  30. data/lib/array.fy +25 -5
  31. data/lib/block.fy +20 -18
  32. data/lib/boot.fy +7 -2
  33. data/lib/class.fy +33 -2
  34. data/lib/compiler/ast.fy +2 -0
  35. data/lib/compiler/ast/assign.fy +5 -5
  36. data/lib/compiler/ast/async_send.fy +25 -0
  37. data/lib/compiler/ast/block.fy +3 -3
  38. data/lib/compiler/ast/future_send.fy +20 -0
  39. data/lib/compiler/ast/identifier.fy +13 -7
  40. data/lib/compiler/ast/match.fy +32 -22
  41. data/lib/compiler/ast/message_send.fy +4 -4
  42. data/lib/compiler/ast/method_def.fy +1 -1
  43. data/lib/compiler/ast/script.fy +2 -2
  44. data/lib/compiler/ast/super.fy +1 -0
  45. data/lib/compiler/compiler.fy +2 -0
  46. data/lib/documentation.fy +4 -4
  47. data/lib/enumerable.fy +14 -7
  48. data/lib/fancy_spec.fy +2 -2
  49. data/lib/fdoc.fy +7 -7
  50. data/lib/fiber.fy +11 -0
  51. data/lib/fiber_pool.fy +78 -0
  52. data/lib/file.fy +1 -1
  53. data/lib/future.fy +32 -0
  54. data/lib/hash.fy +5 -5
  55. data/lib/lazy_array.fy +23 -0
  56. data/lib/main.fy +35 -25
  57. data/lib/method.fy +1 -1
  58. data/lib/nil_class.fy +4 -0
  59. data/lib/object.fy +59 -7
  60. data/lib/package.fy +11 -2
  61. data/lib/package/installer.fy +50 -20
  62. data/lib/package/list.fy +34 -0
  63. data/lib/package/specification.fy +19 -1
  64. data/lib/parser/ext/Makefile +162 -0
  65. data/lib/parser/ext/lexer.c +2360 -0
  66. data/lib/parser/ext/lexer.h +315 -0
  67. data/lib/parser/ext/lexer.lex +4 -0
  68. data/lib/parser/ext/parser.c +3382 -0
  69. data/lib/parser/ext/parser.h +118 -0
  70. data/lib/parser/ext/parser.y +43 -3
  71. data/lib/parser/methods.fy +34 -7
  72. data/lib/parser/parse_error.fy +10 -0
  73. data/lib/proxy.fy +16 -0
  74. data/lib/rbx.fy +3 -0
  75. data/lib/rbx/array.fy +78 -40
  76. data/lib/rbx/block.fy +35 -1
  77. data/lib/rbx/class.fy +5 -3
  78. data/lib/rbx/code_loader.fy +6 -6
  79. data/lib/rbx/console.fy +1 -1
  80. data/lib/rbx/date.fy +12 -0
  81. data/lib/rbx/documentation.fy +5 -5
  82. data/lib/rbx/exception.fy +1 -1
  83. data/lib/rbx/fiber.fy +4 -8
  84. data/lib/rbx/file.fy +4 -3
  85. data/lib/rbx/fixnum.fy +1 -0
  86. data/lib/rbx/float.fy +1 -0
  87. data/lib/rbx/hash.fy +3 -2
  88. data/lib/rbx/io.fy +5 -5
  89. data/lib/rbx/match_data.fy +10 -0
  90. data/lib/rbx/method.fy +4 -4
  91. data/lib/rbx/no_method_error.fy +1 -1
  92. data/lib/rbx/object.fy +8 -15
  93. data/lib/rbx/regexp.fy +4 -0
  94. data/lib/rbx/string.fy +39 -1
  95. data/lib/rbx/symbol.fy +1 -1
  96. data/lib/rbx/system.fy +0 -6
  97. data/lib/rbx/thread.fy +5 -0
  98. data/lib/rbx/time.fy +14 -0
  99. data/lib/rbx/tuple.fy +1 -0
  100. data/lib/set.fy +1 -1
  101. data/lib/stack.fy +1 -1
  102. data/lib/string.fy +2 -2
  103. data/lib/thread_pool.fy +101 -0
  104. data/lib/tuple.fy +37 -6
  105. data/ruby_lib/fancy.rb +46 -0
  106. data/tests/block.fy +39 -0
  107. data/tests/class.fy +40 -1
  108. data/tests/file.fy +2 -2
  109. data/tests/hash.fy +7 -7
  110. data/tests/nil_class.fy +2 -2
  111. data/tests/object.fy +10 -2
  112. data/tests/pattern_matching.fy +18 -7
  113. metadata +34 -7
data/lib/rbx/block.fy CHANGED
@@ -1,9 +1,43 @@
1
1
  # Block = BlockEnvironment
2
2
 
3
3
  class Block {
4
+ ruby_alias: 'arity
5
+
4
6
  def argcount {
5
- "Returns the amount of arguments (arity) a Block takes."
7
+ """
8
+ @return Arity of a @Block@.
9
+
10
+ Returns the amount of arguments (arity) a Block takes.
11
+ """
6
12
 
7
13
  arity()
8
14
  }
15
+
16
+ def receiver {
17
+ """
18
+ @return Receiver object of a @Block@.
19
+
20
+ Returns the receiver of the @Block@ (value for @self)
21
+ """
22
+ @top_scope receiver
23
+ }
24
+
25
+ def receiver: recv {
26
+ """
27
+ @recv New receiver object for a @Block@.
28
+
29
+ Sets the receiver (value for @self) of a @Block@.
30
+ """
31
+ @top_scope receiver: recv
32
+ }
9
33
  }
34
+
35
+ class Rubinius VariableScope {
36
+ def receiver {
37
+ @self
38
+ }
39
+
40
+ def receiver: recv {
41
+ @self = recv
42
+ }
43
+ }
data/lib/rbx/class.fy CHANGED
@@ -2,6 +2,8 @@ class Class {
2
2
  ruby_alias: 'superclass
3
3
  ruby_alias: '===
4
4
  ruby_alias: 'ancestors
5
+ ruby_alias: 'instance_methods
6
+ ruby_alias: 'methods
5
7
 
6
8
  def new {
7
9
  """
@@ -10,7 +12,7 @@ class Class {
10
12
  Creates a new @Class@ instance by subclassing @Object@.
11
13
  """
12
14
 
13
- obj = self allocate()
15
+ obj = allocate()
14
16
  obj initialize
15
17
  obj
16
18
  }
@@ -24,7 +26,7 @@ class Class {
24
26
  Creates a new @Class@ instance by subclassing @superclass.
25
27
  """
26
28
 
27
- obj = self allocate()
29
+ obj = allocate()
28
30
  obj initialize: superclass
29
31
  obj
30
32
  }
@@ -115,7 +117,7 @@ class Class {
115
117
  Returns an instance method for a @Class@ with a given name.
116
118
  """
117
119
 
118
- self instance_method(message_name: name)
120
+ instance_method(message_name: name)
119
121
  }
120
122
 
121
123
  def alias_method_rbx: new_method_name for: old_method_name {
@@ -91,7 +91,7 @@ class Fancy {
91
91
  # Returns the source filename for a given filename.
92
92
  # E.g. "foo.fyc" => "foo.fy"
93
93
  def self source_filename_for: file {
94
- match file -> {
94
+ match file {
95
95
  case /.*\.compiled\.fyc$/ -> file from: 0 to: -14
96
96
  case /.*\.fyc$/ -> file from: 0 to: -2
97
97
  case /\.fy$/ -> file
@@ -102,7 +102,7 @@ class Fancy {
102
102
  # Returns the compiled filename for a given filename.
103
103
  # E.g. "foo.fy" => "foo.fyc", "foo" => "foo.compiled.rbc"
104
104
  def self compiled_filename_for: file {
105
- match file -> {
105
+ match file {
106
106
  case /\.fyc$/ -> file
107
107
  case /\.fy$/ -> file + "c"
108
108
  case _ -> file + ".compiled.fyc"
@@ -184,9 +184,9 @@ class Fancy {
184
184
  load_compiled_file: file find_file: true
185
185
  }
186
186
 
187
- self metaclass send('alias_method, "require:", "fancy_require:")
188
- self metaclass send('alias_method, "load:", "load_compiled_file:")
189
- self metaclass send('alias_method, "load_compiled_file", "load_compiled_file:")
190
- self metaclass send('alias_method, "push_loadpath", "push_loadpath:")
187
+ metaclass send('alias_method, "require:", "fancy_require:")
188
+ metaclass send('alias_method, "load:", "load_compiled_file:")
189
+ metaclass send('alias_method, "load_compiled_file", "load_compiled_file:")
190
+ metaclass send('alias_method, "push_loadpath", "push_loadpath:")
191
191
  }
192
192
  }
data/lib/rbx/console.fy CHANGED
@@ -58,6 +58,6 @@ class Console {
58
58
  def Console clear {
59
59
  "Clears the @Console@."
60
60
 
61
- STDOUT print("\033[H\033[2J")
61
+ Console print: CLEAR_STR
62
62
  }
63
63
  }
data/lib/rbx/date.fy ADDED
@@ -0,0 +1,12 @@
1
+ require("date")
2
+
3
+ class Date {
4
+ metaclass ruby_alias: 'today
5
+ ruby_alias: '==
6
+ ruby_alias: '-
7
+ ruby_alias: '+
8
+
9
+ def != other {
10
+ self == other not
11
+ }
12
+ }
@@ -34,16 +34,16 @@ class Fancy Documentation {
34
34
  fancy docs.
35
35
  """
36
36
 
37
- doc = self allocate()
37
+ doc = allocate()
38
38
  doc send('initialize:, docstring to_s)
39
39
  obj instance_variable_set('@_fancy_documentation, doc)
40
40
 
41
- self documentation_for: obj set_to: doc
41
+ documentation_for: obj set_to: doc
42
42
  doc
43
43
  }
44
44
 
45
- self for: (instance_method('initialize:)) is: "Create a new documentation object."
46
- self for: (method('for:is:)) is: "Sets the documentation for obj."
45
+ for: (instance_method('initialize:)) is: "Create a new documentation object."
46
+ for: (method('for:is:)) is: "Sets the documentation for obj."
47
47
 
48
48
  def self for: obj {
49
49
  "Obtains the Fancy Documentation for obj."
@@ -57,7 +57,7 @@ class Fancy Documentation {
57
57
 
58
58
  def self for: obj append: docstring {
59
59
  "Append docstring to docs."
60
- self for: obj is: docstring
60
+ for: obj is: docstring
61
61
  }
62
62
 
63
63
  }
data/lib/rbx/exception.fy CHANGED
@@ -14,7 +14,7 @@ class StandardError {
14
14
  Creates a new Exception with a given message.
15
15
  """
16
16
 
17
- self initialize(msg)
17
+ initialize(msg)
18
18
  }
19
19
 
20
20
  def raise! {
data/lib/rbx/fiber.fy CHANGED
@@ -3,22 +3,18 @@ require("fiber")
3
3
  Fiber = Rubinius Fiber
4
4
 
5
5
  class Fiber {
6
+ metaclass ruby_alias: 'yield
7
+ ruby_alias: 'resume
8
+ ruby_alias: 'alive?
9
+
6
10
  def self new: block {
7
11
  new(&block)
8
12
  }
9
13
 
10
- def Fiber yield {
11
- yield()
12
- }
13
-
14
14
  def Fiber yield: vals {
15
15
  yield(*vals)
16
16
  }
17
17
 
18
- def resume {
19
- resume()
20
- }
21
-
22
18
  def resume: vals {
23
19
  resume(*vals)
24
20
  }
data/lib/rbx/file.fy CHANGED
@@ -2,7 +2,7 @@ class File {
2
2
  @@open_mode_conversions =
3
3
  <['read => "r",
4
4
  'write => "w",
5
- 'append => "+",
5
+ 'append => "a",
6
6
  'at_end => "a",
7
7
  'binary => "b",
8
8
  'truncate => "w+"]>
@@ -10,6 +10,7 @@ class File {
10
10
  ruby_alias: 'eof?
11
11
  #ruby_alias: 'close
12
12
  ruby_alias: 'closed?
13
+ ruby_alias: 'flush
13
14
 
14
15
  def File open: filename modes: modes_arr with: block {
15
16
  """
@@ -160,7 +161,7 @@ class File {
160
161
  Indicates, if a @File@ is opened.
161
162
  """
162
163
 
163
- self closed? not
164
+ closed? not
164
165
  }
165
166
 
166
167
  def write: str {
@@ -186,6 +187,6 @@ class File {
186
187
  Indicates, if a @File@ is a @Directory@.
187
188
  """
188
189
 
189
- File directory?(self filename)
190
+ File directory?(filename)
190
191
  }
191
192
  }
data/lib/rbx/fixnum.fy CHANGED
@@ -15,6 +15,7 @@ class Fixnum {
15
15
  ruby_alias: '===
16
16
  ruby_alias: 'chr
17
17
  ruby_alias: 'to_i
18
+ ruby_alias: 'to_f
18
19
  ruby_alias: '**
19
20
  ruby_alias: '&
20
21
 
data/lib/rbx/float.fy CHANGED
@@ -10,5 +10,6 @@ class Float {
10
10
  ruby_alias: '<=
11
11
  ruby_alias: '<=>
12
12
  ruby_alias: 'to_i
13
+ ruby_alias: 'to_f
13
14
  ruby_alias: '**
14
15
  }
data/lib/rbx/hash.fy CHANGED
@@ -6,12 +6,13 @@ class Hash {
6
6
  alias_method: 'at: for: '[]
7
7
  ruby_alias: 'keys
8
8
  ruby_alias: 'values
9
+ ruby_alias: '==
9
10
 
10
11
  def inspect {
11
12
  str = "<["
12
- max = self size - 1
13
+ max = size - 1
13
14
  i = 0
14
- self each: |key,val| {
15
+ each: |key,val| {
15
16
  str = str ++ (key inspect) ++ " => " ++ (val inspect)
16
17
  { str = str + ", " } if: (i < max)
17
18
  i = i + 1
data/lib/rbx/io.fy CHANGED
@@ -6,23 +6,23 @@ class IO {
6
6
  ruby_alias: 'eof?
7
7
 
8
8
  def readln {
9
- self readline
9
+ readline
10
10
  }
11
11
 
12
12
  def println {
13
- self puts()
13
+ puts()
14
14
  }
15
15
 
16
16
  def print: obj {
17
- self print(obj)
17
+ print(obj)
18
18
  }
19
19
 
20
20
  def println: obj {
21
- self puts(obj)
21
+ puts(obj)
22
22
  }
23
23
 
24
24
  def printchar: char {
25
- self printc(char)
25
+ printc(char)
26
26
  }
27
27
 
28
28
  alias_method: 'write: for: 'print:
@@ -1,4 +1,6 @@
1
1
  class MatchData {
2
+ ruby_alias: 'size
3
+
2
4
  def at: idx {
3
5
  ruby: '[] args: [idx]
4
6
  }
@@ -6,4 +8,12 @@ class MatchData {
6
8
  def [] idx {
7
9
  at: idx
8
10
  }
11
+
12
+ def to_a {
13
+ arr = []
14
+ self size times: |i| {
15
+ arr << (at: i)
16
+ }
17
+ arr
18
+ }
9
19
  }
data/lib/rbx/method.fy CHANGED
@@ -1,21 +1,21 @@
1
1
  class Method {
2
2
  def documentation {
3
- Fancy Documentation for: (self executable())
3
+ Fancy Documentation for: (executable())
4
4
  }
5
5
 
6
6
  def documentation: str {
7
- Fancy Documentation for: (self executable()) is: str
7
+ Fancy Documentation for: (executable()) is: str
8
8
  }
9
9
  }
10
10
 
11
11
  class UnboundMethod {
12
12
 
13
13
  def documentation {
14
- Fancy Documentation for: (self executable())
14
+ Fancy Documentation for: (executable())
15
15
  }
16
16
 
17
17
  def documentation: str {
18
- Fancy Documentation for: (self executable()) is: str
18
+ Fancy Documentation for: (executable()) is: str
19
19
  }
20
20
 
21
21
  }
@@ -10,6 +10,6 @@ class NoMethodError {
10
10
  Returns the name of the method that was not found as a @String@.
11
11
  """
12
12
 
13
- self name to_s from: 1 to: -1
13
+ name to_s from: 1 to: -1
14
14
  }
15
15
  }
data/lib/rbx/object.fy CHANGED
@@ -17,26 +17,19 @@ class Object {
17
17
  ruby_alias: '==
18
18
  ruby_alias: '===
19
19
  ruby_alias: 'class
20
+ ruby_alias: 'inspect
20
21
 
21
22
  def initialize {
22
- self initialize()
23
+ initialize()
23
24
  }
24
25
 
25
26
  def dclone {
26
27
  "Returns a deep clone of self using Ruby's Marshal class."
27
- Marshal load: $ Marshal dump: self
28
- }
29
-
30
- def ++ other {
31
- self to_s + (other to_s)
28
+ Marshal load(Marshal dump(self))
32
29
  }
33
30
 
34
31
  def to_s {
35
- self to_s()
36
- }
37
-
38
- def inspect {
39
- self inspect()
32
+ to_s()
40
33
  }
41
34
 
42
35
  def set_slot: slotname value: val {
@@ -77,11 +70,11 @@ class Object {
77
70
  }
78
71
 
79
72
  def define_singleton_method: name with: block {
80
- self metaclass define_method: name with: block
73
+ metaclass define_method: name with: block
81
74
  }
82
75
 
83
76
  def undefine_singleton_method: name {
84
- self metaclass undefine_method: name
77
+ metaclass undefine_method: name
85
78
  }
86
79
 
87
80
  def is_a?: class {
@@ -95,7 +88,7 @@ class Object {
95
88
  }
96
89
 
97
90
  def send: message {
98
- self send(message_name: message)
91
+ send(message_name: message)
99
92
  }
100
93
 
101
94
  def send: message params: params {
@@ -112,6 +105,6 @@ class Object {
112
105
  }
113
106
 
114
107
  def responds_to?: message {
115
- self respond_to?(message_name: message)
108
+ respond_to?(message_name: message)
116
109
  }
117
110
  }
data/lib/rbx/regexp.fy CHANGED
@@ -2,6 +2,10 @@ class Regexp {
2
2
  def === string {
3
3
  ruby: 'match args: [string]
4
4
  }
5
+
6
+ def i {
7
+ Regexp new(source(), true)
8
+ }
5
9
  }
6
10
 
7
11
  class MatchData {
data/lib/rbx/string.fy CHANGED
@@ -8,6 +8,7 @@ class String {
8
8
  ruby_alias: 'to_i
9
9
  ruby_alias: 'to_f
10
10
  ruby_alias: 'chomp
11
+ ruby_alias: 'inspect
11
12
 
12
13
  def [] index {
13
14
  """Given an Array of 2 Numbers, it returns the substring between the given indices.
@@ -22,26 +23,58 @@ class String {
22
23
  }
23
24
 
24
25
  def from: from to: to {
26
+ """
27
+ @from Start index.
28
+ @to End index.
29
+ @return Substring starting at index @from and ending at @to.
30
+
31
+ Returns a Substring from @from to @to.
32
+ """
25
33
  ruby: '[] args: [(from .. to)]
26
34
  }
27
35
 
28
36
  def each: block {
37
+ """
38
+ @block @Block to be called for each character in @self.
39
+
40
+ Calls a given @Block with each character in a @String.
41
+ """
29
42
  split("") each(&block)
30
43
  }
31
44
 
32
45
  def at: idx {
46
+ """
47
+ @idx Index of the character to retrieve.
48
+ @return Character in @self at position @idx.
49
+
50
+ Returns the character (as a @String) at index @idx.
51
+ """
33
52
  self[idx]
34
53
  }
35
54
 
36
55
  def split: str {
56
+ """
57
+ @str @String where @self should be split at.
58
+ @return An @Array of @String values in @self that are seperated by @str.
59
+ """
37
60
  split(str)
38
61
  }
39
62
 
40
63
  def split {
64
+ """
65
+ @return @Array of all non-whitespace Substrings in @self.
66
+
67
+ Splits a string by whitespace.
68
+ """
41
69
  split()
42
70
  }
43
71
 
44
72
  def eval {
73
+ """
74
+ @return Value of evaluating @self as Fancy code.
75
+
76
+ Evaluates a @String in the current @Binding and returns its value.
77
+ """
45
78
  binding = Binding setup(Rubinius VariableScope of_sender(),
46
79
  Rubinius CompiledMethod of_sender(),
47
80
  Rubinius StaticScope of_sender())
@@ -49,6 +82,7 @@ class String {
49
82
  }
50
83
 
51
84
  def eval_global {
85
+ "Same as @String#eval but evaluates @self in the global binding."
52
86
  Fancy eval: self
53
87
  }
54
88
 
@@ -57,7 +91,11 @@ class String {
57
91
  }
58
92
 
59
93
  def raise! {
60
- "Raises a new StdError with self as the message."
94
+ "Raises a new StdError with @self as the message."
61
95
  StdError new: self . raise!
62
96
  }
97
+
98
+ def % values {
99
+ ruby: '% args: [values to_a]
100
+ }
63
101
  }