fancy 0.8.0 → 0.9.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 (111) hide show
  1. data/LICENSE +1 -1
  2. data/README.md +5 -4
  3. data/bin/fspec +19 -1
  4. data/bin/ifancy +139 -35
  5. data/boot/README +2 -9
  6. data/boot/extconf.rb +0 -1
  7. data/boot/fancy_ext/module.rb +5 -15
  8. data/boot/fancy_ext/thread.rb +22 -9
  9. data/boot/rbx-compiler/README +0 -4
  10. data/boot/rbx-compiler/parser/fancy_parser.bundle +0 -0
  11. data/boot/rbx-compiler/parser/parser.y +1 -0
  12. data/doc/api/fancy.css +1 -6
  13. data/doc/api/fancy.jsonp +1 -1
  14. data/doc/api/fdoc.js +2 -4
  15. data/doc/api/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  16. data/doc/api/images/ui-bg_flat_0_eeeeee_40x100.png +0 -0
  17. data/doc/api/images/ui-bg_flat_55_ffffff_40x100.png +0 -0
  18. data/doc/api/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  19. data/doc/api/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  20. data/doc/api/images/ui-bg_highlight-soft_100_f6f6f6_1x100.png +0 -0
  21. data/doc/api/images/ui-bg_highlight-soft_25_0073ea_1x100.png +0 -0
  22. data/doc/api/images/ui-bg_highlight-soft_50_dddddd_1x100.png +0 -0
  23. data/doc/api/images/ui-icons_0073ea_256x240.png +0 -0
  24. data/doc/api/images/ui-icons_454545_256x240.png +0 -0
  25. data/doc/api/images/ui-icons_666666_256x240.png +0 -0
  26. data/doc/api/images/ui-icons_ff0084_256x240.png +0 -0
  27. data/doc/api/images/ui-icons_ffffff_256x240.png +0 -0
  28. data/doc/api/index.html +5 -4
  29. data/doc/api/jquery-1.8.2.min.js +2 -0
  30. data/doc/api/jquery-ui-1.9.0.custom.min.css +5 -0
  31. data/doc/api/jquery-ui-1.9.0.custom.min.js +6 -0
  32. data/doc/features.md +8 -3
  33. data/examples/argv.fy +1 -1
  34. data/examples/closures.fy +1 -4
  35. data/examples/echo.fy +2 -2
  36. data/examples/guess_number.fy +18 -0
  37. data/examples/nested_classes.fy +3 -15
  38. data/lib/argv.fy +23 -18
  39. data/lib/array.fy +18 -37
  40. data/lib/block.fy +125 -0
  41. data/lib/boot.fy +1 -0
  42. data/lib/compiler/ast/block.fy +1 -1
  43. data/lib/compiler/ast/identifier.fy +1 -1
  44. data/lib/compiler/ast/message_send.fy +0 -13
  45. data/lib/compiler/ast/method_def.fy +1 -1
  46. data/lib/compiler/ast/singleton_method_def.fy +1 -0
  47. data/lib/compiler/ast/tuple_literal.fy +1 -1
  48. data/lib/compiler/command.fy +1 -1
  49. data/lib/compiler/compiler.fy +8 -6
  50. data/lib/contracts.fy +1 -1
  51. data/lib/directory.fy +1 -1
  52. data/lib/dynamic_slot_object.fy +1 -1
  53. data/lib/enumerable.fy +316 -25
  54. data/lib/enumerator.fy +11 -8
  55. data/lib/eval.fy +0 -3
  56. data/lib/fancy_spec.fy +27 -0
  57. data/lib/fdoc.fy +8 -8
  58. data/lib/file.fy +25 -1
  59. data/lib/hash.fy +91 -0
  60. data/lib/html.fy +40 -11
  61. data/lib/integer.fy +4 -0
  62. data/lib/main.fy +18 -11
  63. data/lib/object.fy +33 -7
  64. data/lib/option_parser.fy +20 -1
  65. data/lib/package/dependency.fy +8 -0
  66. data/lib/package/dependency_installer.fy +3 -6
  67. data/lib/package/handler.fy +4 -4
  68. data/lib/package/installer.fy +2 -5
  69. data/lib/package/list.fy +3 -4
  70. data/lib/parser/ext/parser.y +1 -0
  71. data/lib/proxies.fy +0 -2
  72. data/lib/queue.fy +7 -0
  73. data/lib/rbx.fy +1 -0
  74. data/lib/rbx/actor.fy +3 -1
  75. data/lib/rbx/alpha.fy +24 -0
  76. data/lib/rbx/array.fy +3 -1
  77. data/lib/rbx/class.fy +5 -8
  78. data/lib/rbx/date_time.fy +14 -0
  79. data/lib/rbx/file.fy +6 -0
  80. data/lib/rbx/hash.fy +42 -0
  81. data/lib/rbx/thread.fy +5 -7
  82. data/lib/string.fy +56 -4
  83. data/lib/symbol.fy +29 -1
  84. data/lib/time.fy +17 -0
  85. data/lib/vars.fy +4 -3
  86. data/lib/version.fy +1 -1
  87. data/ruby_lib/interactive/hilight.rb +125 -0
  88. data/tests/array.fy +19 -7
  89. data/tests/block.fy +103 -4
  90. data/tests/class.fy +31 -26
  91. data/tests/control_flow.fy +0 -1
  92. data/tests/dynamic_key_hash.fy +22 -1
  93. data/tests/enumerable.fy +239 -7
  94. data/tests/enumerator.fy +7 -0
  95. data/tests/file.fy +16 -0
  96. data/tests/future.fy +1 -11
  97. data/tests/future_proxy.fy +8 -0
  98. data/tests/hash.fy +132 -9
  99. data/tests/html.fy +30 -13
  100. data/tests/integer.fy +3 -0
  101. data/tests/method.fy +6 -11
  102. data/tests/object.fy +12 -5
  103. data/tests/option_parser.fy +12 -3
  104. data/tests/string.fy +69 -1
  105. data/tests/symbol.fy +24 -0
  106. metadata +42 -12
  107. data/boot/rsexp_pretty_printer.rb +0 -76
  108. data/doc/api/jquery-ui.min.js +0 -401
  109. data/doc/api/jquery.tools.min.js +0 -192
  110. data/doc/api/themeswitchertool.js +0 -250
  111. data/examples/future_sends.fy +0 -15
data/lib/object.fy CHANGED
@@ -139,6 +139,19 @@ class Object {
139
139
  [self]
140
140
  }
141
141
 
142
+ @@__to_hash_exclude_slots__ = ['_fancy_documentation]
143
+ def to_hash {
144
+ """
145
+ @return @Hash@ representation of @self based on slot values.
146
+ """
147
+
148
+ h = <[]>
149
+ slots - @@__to_hash_exclude_slots__ each: |s| {
150
+ h[s]: $ get_slot: s
151
+ }
152
+ h
153
+ }
154
+
142
155
  def to_i {
143
156
  """
144
157
  @return @Fixnum@ representation of @self.
@@ -240,7 +253,17 @@ class Object {
240
253
  cond_block while_do: body_block
241
254
  """
242
255
 
243
- cond_block while_do: body_block
256
+ cond_block while_true: body_block
257
+ }
258
+
259
+ def while: condition do: body else: alternative {
260
+ """
261
+ @condition @Block@ to be used as condition for while loop.
262
+ @body @Block@ to be called while @condition yields @true.
263
+ @alternative @Block@ to be called if @body never got called (@condition never yielded @true).
264
+ """
265
+
266
+ condition while_true: body else: alternative
244
267
  }
245
268
 
246
269
  def until: cond_block do: body_block {
@@ -535,10 +558,13 @@ class Object {
535
558
 
536
559
  Runs a given @Block@ in a synchronized fashion if called by multiple Threads.
537
560
  Uses a @Mutex@ in the background for synchronization (created on demand for each @Object@).
561
+ Calls @block with @self.
538
562
  """
539
563
 
540
564
  @__mutex__ = @__mutex__ || { Mutex new() }
541
- @__mutex__ synchronize(&block)
565
+ @__mutex__ synchronize() {
566
+ block call: [self]
567
+ }
542
568
  }
543
569
 
544
570
  def copy_slots: slots from: object {
@@ -692,18 +718,18 @@ class Object {
692
718
 
693
719
  { return value } unless: var_name
694
720
  unless: block do: {
695
- Thread current[var_name]: value
721
+ Thread current set_dynamic_var: var_name to: value
696
722
  return value
697
723
  }
698
724
 
699
- oldval = Thread current[var_name]
725
+ oldval = Thread current dynamic_var: var_name
700
726
  try {
701
- Thread current[var_name]: value
727
+ Thread current set_dynamic_var: var_name to: value
702
728
  block call
703
729
  return value
704
730
  } finally {
705
731
  try { ensure_block call } catch {}
706
- Thread current[var_name]: oldval
732
+ Thread current set_dynamic_var: var_name to: oldval
707
733
  }
708
734
  }
709
735
 
@@ -772,7 +798,7 @@ class Object {
772
798
  @block @Block@ to be executed while ignoring (catching but not handling) @Exception@s defined in @exception_classes.
773
799
 
774
800
  Example:
775
- ignoring: (IOError, ZeroDivisionError) in: {
801
+ ignoring: (IOError, ZeroDivisionError) do: {
776
802
  # do something
777
803
  }
778
804
  """
data/lib/option_parser.fy CHANGED
@@ -50,7 +50,7 @@ class OptionParser {
50
50
  { @block call: [self] } if: @block
51
51
  }
52
52
 
53
- def with: option_string doc: doc_string do: block {
53
+ def with: option_string doc: doc_string do: block ('identity) {
54
54
  """
55
55
  @option_string Option flag and (optional) argument within \"[]\", e.g. \"--file [filename]\".
56
56
  @doc_string Documentation @String@ for @option_string that is used in the standard @--help option.
@@ -100,6 +100,25 @@ class OptionParser {
100
100
  }
101
101
  }
102
102
 
103
+ def parse_hash: args {
104
+ """
105
+ @args @Array@ of arguments to parse options from. Typically you'd pass @ARGV here.
106
+
107
+ Parses options as @Hash@ from @args and executes registered option handlers.
108
+
109
+ Example:
110
+ o = OptionParser new: @{
111
+ with: \"--some-option [option_value]\" doc: \"some docstring\"
112
+ # ...
113
+ }
114
+ opts = o parse_hash: [\"--some-option\", \"some-value\"]
115
+ opts # => <[\"--some-option\" => \"some-value\"]>
116
+ """
117
+
118
+ parse: args
119
+ parsed_options
120
+ }
121
+
103
122
  def print_help_info {
104
123
  """
105
124
  Displays the @--help information on @*stdout* based on all options that were registered via @OptionParser#with:doc:do:@.
@@ -7,6 +7,14 @@ class Fancy Package {
7
7
 
8
8
  read_slots: ('name, 'version)
9
9
  def initialize: @name version: @version ('latest);
10
+
11
+ def install {
12
+ """
13
+ Installs the Dependency on the System.
14
+ """
15
+
16
+ Fancy Package install: name version: version
17
+ }
10
18
  }
11
19
 
12
20
  class RubyDependency {
@@ -8,15 +8,12 @@ class Fancy {
8
8
  return nil
9
9
  }
10
10
 
11
- require: packfile
12
-
13
- spec_name = packfile split: ".fancypack" . first
14
- if: (Specification[spec_name]) then: |s| {
15
- s dependencies each: |dep| {
11
+ if: (File eval: packfile) then: |spec| {
12
+ spec dependencies each: |dep| {
16
13
  "Installing dependency: #{dep name} (#{dep version})" println
17
14
  Fancy Package install: (dep name) version: (dep version)
18
15
  }
19
- s ruby_dependencies each: |dep| {
16
+ spec ruby_dependencies each: |dep| {
20
17
  "Installing Ruby dependency: #{dep gem_name} (#{dep version})" println
21
18
  dep install
22
19
  }
@@ -34,11 +34,11 @@ class Fancy Package {
34
34
  If no @.fancypack file is found, raise an error.
35
35
  """
36
36
 
37
- Dir glob(installed_path ++ "/*.fancypack") first if_true: |fpackfile| {
38
- require: fpackfile
37
+ spec = nil
38
+ if: (Dir glob(installed_path ++ "/*.fancypack") first) then: |fpackfile| {
39
+ spec = File eval: fpackfile
39
40
  }
40
-
41
- if: (Specification[@repository]) then: success_block else: else_block
41
+ if: spec then: success_block else: else_block
42
42
  }
43
43
 
44
44
  def installed_path {
@@ -193,11 +193,8 @@ class Fancy Package {
193
193
  File symlink(orig_path, link_path)
194
194
  }
195
195
 
196
- spec dependencies each: |dep| {
197
- Fancy Package install: (dep name) version: (dep version)
198
- }
199
-
200
- spec ruby_dependencies each: |dep| { dep install }
196
+ spec dependencies each: @{ install }
197
+ spec ruby_dependencies each: @{ install }
201
198
  }
202
199
  }
203
200
  }
data/lib/package/list.fy CHANGED
@@ -5,13 +5,14 @@ class Fancy Package {
5
5
  def println {
6
6
  packages each: |p| {
7
7
  name, version, url = p
8
- "#{name} (#{version})" println
8
+ "#{name} (#{version}) - #{url}" println
9
9
  }
10
10
  }
11
11
 
12
12
  def packages {
13
13
  packages = []
14
- try {
14
+ # ignore file not found, as no packages might have been installed yet.
15
+ ignoring: IOError do: {
15
16
  File open: @package_list_file modes: ['read] with: |f| {
16
17
  f readlines each: |l| {
17
18
  match l {
@@ -20,8 +21,6 @@ class Fancy Package {
20
21
  }
21
22
  }
22
23
  }
23
- } catch IOError => e {
24
- # ignore file not found, as no packages might have been installed yet.
25
24
  }
26
25
  packages
27
26
  }
@@ -161,6 +161,7 @@ extern char *yytext;
161
161
  %%
162
162
 
163
163
  programm: /*empty*/
164
+ | nls
164
165
  | expression_list {
165
166
  rb_funcall(self, rb_intern("body:"), 1, $1);
166
167
  }
data/lib/proxies.fy CHANGED
@@ -29,8 +29,6 @@ class Proxies {
29
29
  }
30
30
  }
31
31
 
32
- Proxy = ProxyReceiver
33
-
34
32
  class RespondsToProxy : Fancy BasicObject {
35
33
  """
36
34
  A RespondsToProxy is a Proxy that forwards any message sent to it to it's @target instance variable
data/lib/queue.fy ADDED
@@ -0,0 +1,7 @@
1
+ class Queue {
2
+ forwards_unary_ruby_methods
3
+
4
+ ruby_aliases: ['<<, 'clear, 'deq, 'empty?, 'length, 'num_waiting, 'pop, 'shift, 'size]
5
+ alias_method: 'push: for_ruby: 'push
6
+ alias_method: 'enqueue: for_ruby: 'enq
7
+ }
data/lib/rbx.fy CHANGED
@@ -38,6 +38,7 @@ require: "rbx/thread"
38
38
  require: "rbx/fiber"
39
39
  require: "rbx/date"
40
40
  require: "rbx/time"
41
+ require: "rbx/date_time"
41
42
  require: "rbx/actor"
42
43
  require: "rbx/mutex"
43
44
  require: "rbx/module"
data/lib/rbx/actor.fy CHANGED
@@ -1,4 +1,6 @@
1
- require("actor")
1
+ require("rubygems")
2
+ require("rubinius/actor")
3
+ Actor = Rubinius Actor
2
4
 
3
5
  class Actor {
4
6
  """
data/lib/rbx/alpha.fy CHANGED
@@ -34,4 +34,28 @@ class Class {
34
34
 
35
35
  class String {
36
36
  alias_method: ":+" for: "+"
37
+ alias_method: ":to_sym" for: "to_sym"
38
+ }
39
+
40
+ class Module {
41
+ def included: module
42
+
43
+ def include: modules {
44
+ modules = modules to_a()
45
+ modules reverse_each() |mod| {
46
+ mod append_features: self
47
+ mod send('included, self)
48
+ }
49
+ }
50
+ }
51
+
52
+ class Class{
53
+ def include: modules {
54
+ modules = modules to_a()
55
+ modules reverse_each() |mod| {
56
+ mod append_features: self
57
+ mod send('included, self)
58
+ mod included: self
59
+ }
60
+ }
37
61
  }
data/lib/rbx/array.fy CHANGED
@@ -1,5 +1,7 @@
1
1
  class Array {
2
- ruby_aliases: [ '==, '<<, 'pop, 'last, 'shift, 'flatten ]
2
+ ruby_aliases: [ '==, '<<, 'pop, 'last, 'shift, 'flatten, 'flatten! ]
3
+ alias_method: 'flatten: for_ruby: 'flatten
4
+ alias_method: 'flatten!: for_ruby: 'flatten!
3
5
 
4
6
  forwards_unary_ruby_methods
5
7
 
data/lib/rbx/class.fy CHANGED
@@ -114,12 +114,12 @@ class Class {
114
114
 
115
115
  def nested_classes {
116
116
  """
117
- @return @Array@ of all nested classes for @self.
117
+ @return @Set@ of all nested classes for @self.
118
118
 
119
119
  Returns all the nested classes within a @Class@ as an @Array@.
120
120
  """
121
121
 
122
- "Not Yet Implemented" raise!
122
+ Set[constants map: |c| { const_get(c) } . select: @{ is_a?: Class }]
123
123
  }
124
124
 
125
125
  def instance_method: name {
@@ -160,8 +160,7 @@ class Class {
160
160
  Sets any given method names to public on this @Class@.
161
161
  """
162
162
 
163
- method_names = method_names to_a()
164
- method_names = method_names map: |m| { m message_name }
163
+ method_names = method_names to_a() map() @{ message_name }
165
164
  public(*method_names)
166
165
  }
167
166
 
@@ -172,8 +171,7 @@ class Class {
172
171
  Sets any given method names to private on this @Class@.
173
172
  """
174
173
 
175
- method_names = method_names to_a()
176
- method_names = method_names map() |m| { m message_name }
174
+ method_names = method_names to_a() map() @{ message_name }
177
175
  private(*method_names)
178
176
  }
179
177
 
@@ -184,8 +182,7 @@ class Class {
184
182
  Sets any given method names to protected on this @Class@.
185
183
  """
186
184
 
187
- method_names = method_names to_a()
188
- method_names = method_names map() |m| { m message_name }
185
+ method_names = method_names to_a() map() @{ message_name }
189
186
  protected(*method_names)
190
187
  }
191
188
 
@@ -0,0 +1,14 @@
1
+ class DateTime {
2
+ # """
3
+ # DateTime class. Used for yet more timely stuff.
4
+ # """
5
+
6
+ forwards_unary_ruby_methods
7
+
8
+ metaclass ruby_alias: 'now
9
+ ruby_aliases: [ '==, '-, '+, '<, '>, '<=, '>= ]
10
+
11
+ def != other {
12
+ self == other not
13
+ }
14
+ }
data/lib/rbx/file.fy CHANGED
@@ -8,7 +8,9 @@ class File {
8
8
  'truncate => "w+"]>
9
9
 
10
10
  ruby_aliases: [ 'eof?, 'closed?, 'flush ]
11
+
11
12
  metaclass alias_method: 'expand_path: for_ruby: 'expand_path
13
+ metaclass alias_method: 'dirname: for_ruby: 'dirname
12
14
 
13
15
  forwards_unary_ruby_methods
14
16
 
@@ -170,6 +172,10 @@ class File {
170
172
  File expand_path: filename
171
173
  }
172
174
 
175
+ def File join: path_components {
176
+ File join(*path_components)
177
+ }
178
+
173
179
  def initialize: path {
174
180
  initialize(path)
175
181
  }
data/lib/rbx/hash.fy CHANGED
@@ -7,6 +7,17 @@ class Hash {
7
7
  alias_method: 'at: for: '[]
8
8
  ruby_alias: '==
9
9
 
10
+ def initialize: default {
11
+ """
12
+ @default Default value for @self.
13
+
14
+ Initializes a new @Hash@ with @default as a default value.
15
+ If @default is a @Block@, call it with @self and a given key to get its default value.
16
+ """
17
+
18
+ default: default
19
+ }
20
+
10
21
  def each: block {
11
22
  each(&block)
12
23
  }
@@ -51,4 +62,35 @@ class Hash {
51
62
 
52
63
  include?(key)
53
64
  }
65
+
66
+ def default: default_value {
67
+ """
68
+ @default_value Default value for @self.
69
+
70
+ Sets the default value to be returned from @self for keys not in @self.
71
+ If @default_value is a @Block@, use its return value (called with the @Hash@ and a given key).
72
+ """
73
+
74
+ match default_value {
75
+ case Block -> @default_proc = true
76
+ }
77
+ @default = default_value
78
+ }
79
+
80
+ def default {
81
+ """
82
+ @return Default value for @self.
83
+ """
84
+
85
+ @default
86
+ }
87
+
88
+ def default_for: key {
89
+ """
90
+ @key Key to be used.
91
+ @return Default value for @key.
92
+ """
93
+
94
+ default(key)
95
+ }
54
96
  }
data/lib/rbx/thread.fy CHANGED
@@ -35,15 +35,13 @@ 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
38
 
40
- def [dynamic_var_name] {
41
- send('[], dynamic_var_name)
42
- }
39
+ ruby_alias: 'dynamic_vars
40
+ alias_method: 'dynamic_var: for_ruby: 'get_dynamic_variable
41
+ alias_method: 'set_dynamic_var:to: for_ruby: 'set_dynamic_variable
43
42
 
44
- def [dynamic_var_name]: value {
45
- send('[]=, dynamic_var_name, value)
46
- }
43
+ alias_method: '[] for_ruby: '[]
44
+ alias_method: '[]: for_ruby: '[]=
47
45
 
48
46
  def priority: new_prio {
49
47
  priority=(new_prio)