fancy 0.3.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.
- data/AUTHORS +7 -0
- data/LICENSE +19 -0
- data/README +173 -0
- data/Rakefile +255 -0
- data/bin/fancy +40 -0
- data/bin/fdoc +23 -0
- data/bin/fyi +22 -0
- data/bin/ifancy +46 -0
- data/boot/README +12 -0
- data/boot/code_loader.rb +165 -0
- data/boot/compile.fy +3 -0
- data/boot/fancy_ext.rb +13 -0
- data/boot/fancy_ext/block_env.rb +29 -0
- data/boot/fancy_ext/class.rb +26 -0
- data/boot/fancy_ext/kernel.rb +12 -0
- data/boot/fancy_ext/module.rb +89 -0
- data/boot/fancy_ext/object.rb +34 -0
- data/boot/fancy_ext/string_helper.rb +10 -0
- data/boot/load.rb +72 -0
- data/boot/rbx-compiler/README +12 -0
- data/boot/rbx-compiler/compiler.rb +24 -0
- data/boot/rbx-compiler/compiler/ast.rb +23 -0
- data/boot/rbx-compiler/compiler/ast/README +11 -0
- data/boot/rbx-compiler/compiler/ast/array_literal.rb +13 -0
- data/boot/rbx-compiler/compiler/ast/assign.rb +57 -0
- data/boot/rbx-compiler/compiler/ast/block.rb +70 -0
- data/boot/rbx-compiler/compiler/ast/class_def.rb +35 -0
- data/boot/rbx-compiler/compiler/ast/expression_list.rb +57 -0
- data/boot/rbx-compiler/compiler/ast/hash_literal.rb +11 -0
- data/boot/rbx-compiler/compiler/ast/identifier.rb +120 -0
- data/boot/rbx-compiler/compiler/ast/match.rb +81 -0
- data/boot/rbx-compiler/compiler/ast/message_send.rb +71 -0
- data/boot/rbx-compiler/compiler/ast/method_def.rb +116 -0
- data/boot/rbx-compiler/compiler/ast/node.rb +6 -0
- data/boot/rbx-compiler/compiler/ast/range_literal.rb +22 -0
- data/boot/rbx-compiler/compiler/ast/require.rb +20 -0
- data/boot/rbx-compiler/compiler/ast/return.rb +29 -0
- data/boot/rbx-compiler/compiler/ast/ruby_args.rb +35 -0
- data/boot/rbx-compiler/compiler/ast/script.rb +56 -0
- data/boot/rbx-compiler/compiler/ast/singleton_method_def.rb +39 -0
- data/boot/rbx-compiler/compiler/ast/string_literal.rb +14 -0
- data/boot/rbx-compiler/compiler/ast/super.rb +25 -0
- data/boot/rbx-compiler/compiler/ast/try_catch_block.rb +220 -0
- data/boot/rbx-compiler/compiler/ast/tuple_literal.rb +33 -0
- data/boot/rbx-compiler/compiler/command.rb +39 -0
- data/boot/rbx-compiler/compiler/compiler.rb +83 -0
- data/boot/rbx-compiler/compiler/stages.rb +99 -0
- data/boot/rbx-compiler/parser.rb +2 -0
- data/boot/rbx-compiler/parser/README +15 -0
- data/boot/rbx-compiler/parser/Rakefile +54 -0
- data/boot/rbx-compiler/parser/extconf.rb +3 -0
- data/boot/rbx-compiler/parser/fancy_parser.bundle +0 -0
- data/boot/rbx-compiler/parser/fancy_parser.c +46 -0
- data/boot/rbx-compiler/parser/fancy_parser.h +8 -0
- data/boot/rbx-compiler/parser/lexer.lex +180 -0
- data/boot/rbx-compiler/parser/parser.rb +356 -0
- data/boot/rbx-compiler/parser/parser.y +711 -0
- data/boot/rsexp_pretty_printer.rb +76 -0
- data/doc/api/fancy.css +93 -0
- data/doc/api/fancy.jsonp +1 -0
- data/doc/api/fdoc.js +187 -0
- data/doc/api/index.html +57 -0
- data/doc/api/underscore-min.js +18 -0
- data/doc/features.md +228 -0
- data/examples/argv.fy +8 -0
- data/examples/arithmetic.fy +7 -0
- data/examples/armstrong_numbers.fy +33 -0
- data/examples/array.fy +52 -0
- data/examples/blocks.fy +15 -0
- data/examples/boolean.fy +24 -0
- data/examples/call_with_receiver.fy +9 -0
- data/examples/class.fy +68 -0
- data/examples/closures.fy +24 -0
- data/examples/constant_access.fy +15 -0
- data/examples/default_args.fy +17 -0
- data/examples/define_methods.fy +15 -0
- data/examples/documentation.fy +57 -0
- data/examples/documentation_formatters.fy +25 -0
- data/examples/echo.fy +16 -0
- data/examples/empty_catch.fy +4 -0
- data/examples/exception.fy +9 -0
- data/examples/factorial.fy +12 -0
- data/examples/fibonacci.fy +16 -0
- data/examples/files.fy +23 -0
- data/examples/finally.fy +5 -0
- data/examples/game_of_life.fy +148 -0
- data/examples/hashes.fy +7 -0
- data/examples/hello_world.fy +6 -0
- data/examples/html_generator.fy +54 -0
- data/examples/implicit_return.fy +3 -0
- data/examples/matchers.fy +6 -0
- data/examples/methods.fy +29 -0
- data/examples/nested_classes.fy +27 -0
- data/examples/nested_try.fy +9 -0
- data/examples/numbers.fy +12 -0
- data/examples/pattern_matching.fy +40 -0
- data/examples/person.fy +65 -0
- data/examples/project-euler/01.fy +8 -0
- data/examples/project-euler/02.fy +21 -0
- data/examples/project-euler/28.fy +33 -0
- data/examples/rbx/and_or.fy +7 -0
- data/examples/rbx/blocks.fy +22 -0
- data/examples/rbx/classes.fy +32 -0
- data/examples/rbx/hello.fy +8 -0
- data/examples/rbx/include.fy +12 -0
- data/examples/rbx/inherit.fy +11 -0
- data/examples/rbx/methods.fy +15 -0
- data/examples/rbx/nested_classes.fy +9 -0
- data/examples/rbx/require.fy +3 -0
- data/examples/rbx/strings.fy +5 -0
- data/examples/regex.fy +7 -0
- data/examples/require.fy +7 -0
- data/examples/retry.fy +12 -0
- data/examples/return.fy +13 -0
- data/examples/ruby_require.fy +7 -0
- data/examples/ruby_send.fy +3 -0
- data/examples/singleton_methods.fy +21 -0
- data/examples/stupid_quicksort.fy +12 -0
- data/examples/threads.fy +18 -0
- data/examples/tuple.fy +8 -0
- data/examples/webserver/webserver.fy +18 -0
- data/lib/argv.fy +36 -0
- data/lib/array.fy +207 -0
- data/lib/block.fy +88 -0
- data/lib/boot.fy +41 -0
- data/lib/class.fy +106 -0
- data/lib/compiler.fy +14 -0
- data/lib/compiler/ast.fy +40 -0
- data/lib/compiler/ast/assign.fy +96 -0
- data/lib/compiler/ast/block.fy +84 -0
- data/lib/compiler/ast/class_def.fy +33 -0
- data/lib/compiler/ast/expression_list.fy +47 -0
- data/lib/compiler/ast/identifier.fy +113 -0
- data/lib/compiler/ast/literals.fy +122 -0
- data/lib/compiler/ast/match.fy +88 -0
- data/lib/compiler/ast/message_send.fy +110 -0
- data/lib/compiler/ast/method_def.fy +90 -0
- data/lib/compiler/ast/node.fy +7 -0
- data/lib/compiler/ast/range.fy +16 -0
- data/lib/compiler/ast/require.fy +15 -0
- data/lib/compiler/ast/return.fy +23 -0
- data/lib/compiler/ast/script.fy +52 -0
- data/lib/compiler/ast/singleton_method_def.fy +35 -0
- data/lib/compiler/ast/super.fy +17 -0
- data/lib/compiler/ast/try_catch.fy +176 -0
- data/lib/compiler/ast/tuple_literal.fy +34 -0
- data/lib/compiler/command.fy +51 -0
- data/lib/compiler/compiler.fy +73 -0
- data/lib/compiler/stages.fy +81 -0
- data/lib/directory.fy +17 -0
- data/lib/documentation.fy +115 -0
- data/lib/enumerable.fy +269 -0
- data/lib/eval.fy +31 -0
- data/lib/fancy_spec.fy +202 -0
- data/lib/fdoc.fy +359 -0
- data/lib/fdoc_hook.fy +10 -0
- data/lib/file.fy +54 -0
- data/lib/hash.fy +56 -0
- data/lib/main.fy +80 -0
- data/lib/method.fy +22 -0
- data/lib/nil_class.fy +56 -0
- data/lib/number.fy +87 -0
- data/lib/object.fy +170 -0
- data/lib/package.fy +61 -0
- data/lib/package/dependency.fy +24 -0
- data/lib/package/installer.fy +180 -0
- data/lib/package/specification.fy +55 -0
- data/lib/package/uninstaller.fy +15 -0
- data/lib/parser.fy +4 -0
- data/lib/parser/ext/README +15 -0
- data/lib/parser/ext/ext.c +42 -0
- data/lib/parser/ext/ext.h +8 -0
- data/lib/parser/ext/extconf.rb +3 -0
- data/lib/parser/ext/lexer.lex +187 -0
- data/lib/parser/ext/parser.y +744 -0
- data/lib/parser/methods.fy +297 -0
- data/lib/rbx.fy +37 -0
- data/lib/rbx/array.fy +237 -0
- data/lib/rbx/bignum.fy +23 -0
- data/lib/rbx/block.fy +9 -0
- data/lib/rbx/class.fy +129 -0
- data/lib/rbx/code_loader.fy +192 -0
- data/lib/rbx/console.fy +63 -0
- data/lib/rbx/directory.fy +46 -0
- data/lib/rbx/documentation.fy +64 -0
- data/lib/rbx/environment_variables.fy +3 -0
- data/lib/rbx/exception.fy +30 -0
- data/lib/rbx/false_class.fy +58 -0
- data/lib/rbx/fiber.fy +25 -0
- data/lib/rbx/file.fy +191 -0
- data/lib/rbx/fixnum.fy +25 -0
- data/lib/rbx/float.fy +14 -0
- data/lib/rbx/hash.fy +38 -0
- data/lib/rbx/integer.fy +15 -0
- data/lib/rbx/io.fy +30 -0
- data/lib/rbx/match_data.fy +9 -0
- data/lib/rbx/method.fy +22 -0
- data/lib/rbx/name_error.fy +3 -0
- data/lib/rbx/no_method_error.fy +15 -0
- data/lib/rbx/object.fy +117 -0
- data/lib/rbx/range.fy +15 -0
- data/lib/rbx/regexp.fy +9 -0
- data/lib/rbx/string.fy +63 -0
- data/lib/rbx/symbol.fy +12 -0
- data/lib/rbx/system.fy +37 -0
- data/lib/rbx/tcp_server.fy +6 -0
- data/lib/rbx/tcp_socket.fy +7 -0
- data/lib/rbx/thread.fy +75 -0
- data/lib/rbx/tuple.fy +37 -0
- data/lib/set.fy +61 -0
- data/lib/stack.fy +51 -0
- data/lib/string.fy +58 -0
- data/lib/struct.fy +13 -0
- data/lib/symbol.fy +23 -0
- data/lib/true_class.fy +43 -0
- data/lib/tuple.fy +68 -0
- data/lib/version.fy +6 -0
- data/tests/argv.fy +13 -0
- data/tests/array.fy +343 -0
- data/tests/assignment.fy +53 -0
- data/tests/block.fy +103 -0
- data/tests/class.fy +409 -0
- data/tests/control_flow.fy +79 -0
- data/tests/documentation.fy +24 -0
- data/tests/exception.fy +115 -0
- data/tests/file.fy +86 -0
- data/tests/hash.fy +101 -0
- data/tests/method.fy +131 -0
- data/tests/nil_class.fy +55 -0
- data/tests/number.fy +128 -0
- data/tests/object.fy +125 -0
- data/tests/parsing/sexp.fy +50 -0
- data/tests/pattern_matching.fy +82 -0
- data/tests/range.fy +11 -0
- data/tests/set.fy +10 -0
- data/tests/stack.fy +22 -0
- data/tests/string.fy +102 -0
- data/tests/symbol.fy +17 -0
- data/tests/true_class.fy +63 -0
- data/tests/tuple.fy +21 -0
- data/tools/fancy-mode.el +63 -0
- metadata +321 -0
data/lib/package.fy
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
require: "package/installer"
|
2
|
+
require: "package/uninstaller"
|
3
|
+
require: "package/dependency"
|
4
|
+
require: "package/specification"
|
5
|
+
|
6
|
+
class Fancy Package {
|
7
|
+
"""
|
8
|
+
|
9
|
+
The Fancy Package System.
|
10
|
+
|
11
|
+
This class is used for installing and uninstalling fancy packages on
|
12
|
+
the system.
|
13
|
+
|
14
|
+
Example:
|
15
|
+
$ fancy install bakkdoor/mongo.fy
|
16
|
+
|
17
|
+
Will install the mongo.fy package from http://github.com/bakkdoor/mongo.fy
|
18
|
+
in the latest released version or get the current HEAD (master
|
19
|
+
branch) revision.
|
20
|
+
|
21
|
+
You can then load the package in your source file via
|
22
|
+
require: \"mongo.fy\"
|
23
|
+
|
24
|
+
"""
|
25
|
+
|
26
|
+
ENV_PACKAGE_DIR_VAR = "FANCY_PACKAGE_DIR"
|
27
|
+
|
28
|
+
def self install: package_name {
|
29
|
+
"""
|
30
|
+
Installs a package with a given name.
|
31
|
+
Expects package_name to be a string in the form of:
|
32
|
+
user/repo
|
33
|
+
Which would get the package code from github.com/user/repo
|
34
|
+
"""
|
35
|
+
|
36
|
+
Installer new: package_name . run
|
37
|
+
}
|
38
|
+
|
39
|
+
def self uninstall: package_name {
|
40
|
+
Uninstaller new: package_name . run
|
41
|
+
}
|
42
|
+
|
43
|
+
def self package_root_dir {
|
44
|
+
if: (ENV[ENV_PACKAGE_DIR_VAR]) then: |path| {
|
45
|
+
return path
|
46
|
+
} else: {
|
47
|
+
return Fancy Package Installer DEFAULT_PACKAGES_PATH
|
48
|
+
}
|
49
|
+
}
|
50
|
+
|
51
|
+
def self add_to_loadpath {
|
52
|
+
"""
|
53
|
+
Adds the Fancy Package install dir to the loadpath so you can
|
54
|
+
easily @require: packages into your code.
|
55
|
+
"""
|
56
|
+
|
57
|
+
root = Fancy Package package_root_dir
|
58
|
+
Fancy CodeLoader push_loadpath: root
|
59
|
+
Fancy CodeLoader push_loadpath: (root ++ "/lib")
|
60
|
+
}
|
61
|
+
}
|
@@ -0,0 +1,24 @@
|
|
1
|
+
class Fancy Package {
|
2
|
+
class Dependency {
|
3
|
+
"""
|
4
|
+
Package Dependency.
|
5
|
+
Represents a Dependency to another Package with a given version.
|
6
|
+
"""
|
7
|
+
|
8
|
+
read_slots: ['name, 'version]
|
9
|
+
|
10
|
+
def initialize: @name version: @version ('latest) {
|
11
|
+
}
|
12
|
+
}
|
13
|
+
|
14
|
+
class RubyDependency {
|
15
|
+
"""
|
16
|
+
Same as @Fancy::Package::Dependency@, just for rubygem packages.
|
17
|
+
"""
|
18
|
+
|
19
|
+
read_slots: ['gem_name, 'version]
|
20
|
+
|
21
|
+
def initialize: @gem_name version: @version ('latest) {
|
22
|
+
}
|
23
|
+
}
|
24
|
+
}
|
@@ -0,0 +1,180 @@
|
|
1
|
+
require("yaml")
|
2
|
+
require("open-uri")
|
3
|
+
|
4
|
+
class Fancy Package {
|
5
|
+
class Installer {
|
6
|
+
"""
|
7
|
+
|
8
|
+
@Fancy::Package@ installer.
|
9
|
+
|
10
|
+
Downloads packages from Github (usually the latest tagged version,
|
11
|
+
if no version is specified, or the latest HEAD revision in the
|
12
|
+
master branch) and install it to the @FANCY_PACKAGE_DIR.
|
13
|
+
|
14
|
+
"""
|
15
|
+
|
16
|
+
DEFAULT_FANCY_ROOT = ENV["HOME"] ++ "/.fancy"
|
17
|
+
DEFAULT_PACKAGES_PATH = DEFAULT_FANCY_ROOT ++ "/packages"
|
18
|
+
DEFAULT_PACKAGES_LIB_PATH = DEFAULT_PACKAGES_PATH ++ "/lib"
|
19
|
+
|
20
|
+
def initialize: @package_name version: @version ("latest") install_path: @install_path (ENV["FANCY_PACKAGE_DIR"]) {
|
21
|
+
"""
|
22
|
+
Creates a new @Package Installer@ for a given package name, an
|
23
|
+
optional version (default is 'latest') and an optional
|
24
|
+
installation path (default is the standard installation path for
|
25
|
+
Fancy packages).
|
26
|
+
"""
|
27
|
+
|
28
|
+
splitted = @package_name split: "/"
|
29
|
+
@user = splitted first
|
30
|
+
@repository = splitted second
|
31
|
+
|
32
|
+
@install_path if_nil: {
|
33
|
+
@install_path = DEFAULT_PACKAGES_PATH
|
34
|
+
Directory create!: DEFAULT_FANCY_ROOT
|
35
|
+
Directory create!: DEFAULT_PACKAGES_PATH
|
36
|
+
Directory create!: DEFAULT_PACKAGES_LIB_PATH
|
37
|
+
Directory create!: $ DEFAULT_PACKAGES_PATH ++ "/downloads"
|
38
|
+
}
|
39
|
+
|
40
|
+
@download_path = @install_path ++ "/downloads"
|
41
|
+
}
|
42
|
+
|
43
|
+
def run {
|
44
|
+
"""
|
45
|
+
Runs the installer & installs the package into
|
46
|
+
@$FANCY_PACKAGE_DIR.
|
47
|
+
"""
|
48
|
+
|
49
|
+
filename = nil
|
50
|
+
if: (@version == "latest") then: {
|
51
|
+
if: (self latest_tag) then: |tag| {
|
52
|
+
@version = tag
|
53
|
+
} else: {
|
54
|
+
@version = "master"
|
55
|
+
}
|
56
|
+
filename = self download_tgz: @version
|
57
|
+
}
|
58
|
+
|
59
|
+
# now unpack & check for dependencies
|
60
|
+
unpack_dir = unpack_file: filename
|
61
|
+
rename_dir: unpack_dir
|
62
|
+
self load_fancypack
|
63
|
+
}
|
64
|
+
|
65
|
+
def latest_tag {
|
66
|
+
"Returns the latest tag (sorted alphabetically)."
|
67
|
+
|
68
|
+
tags = self tags
|
69
|
+
if: (tags size > 0) then: {
|
70
|
+
tags keys sort last
|
71
|
+
}
|
72
|
+
}
|
73
|
+
|
74
|
+
def tags {
|
75
|
+
"Returns a list of tags the repository has on Github."
|
76
|
+
|
77
|
+
url = "http://github.com/api/v2/yaml/repos/show/" ++ @package_name ++ "/tags/"
|
78
|
+
YAML load_stream(open(url)) documents() first at: "tags"
|
79
|
+
}
|
80
|
+
|
81
|
+
def download_url: version {
|
82
|
+
"""
|
83
|
+
Returns the download url for a given version of the package
|
84
|
+
to be installed.
|
85
|
+
"""
|
86
|
+
|
87
|
+
"https://github.com/" ++ @package_name ++ "/tarball/" ++ version
|
88
|
+
}
|
89
|
+
|
90
|
+
def download_tgz: version {
|
91
|
+
"""
|
92
|
+
Downloads the .tar.gz file from Github with the given version
|
93
|
+
(tag or branch name) and saves it to the specified @install_path.
|
94
|
+
|
95
|
+
|
96
|
+
The Default install_path is ~/.fancy/packages/.
|
97
|
+
If an environment variable @FANCY_PACKAGE_DIR is defined, it
|
98
|
+
will get used.
|
99
|
+
"""
|
100
|
+
|
101
|
+
download_url = download_url: version
|
102
|
+
["Downloading ", @package_name, " version ", version, " from: ", download_url] join println
|
103
|
+
|
104
|
+
filename = [@user, "_", @repository, "-", version, ".tar.gz"] join
|
105
|
+
|
106
|
+
# run curl to get the .tar.gz file
|
107
|
+
cmd = ["curl -o ", @download_path, "/", filename, " -L -O ", download_url] join
|
108
|
+
System do: cmd
|
109
|
+
|
110
|
+
filename
|
111
|
+
}
|
112
|
+
|
113
|
+
def unpack_file: filename {
|
114
|
+
"Unpacking " ++ filename println
|
115
|
+
System do: $ ["tar xf ", @download_path, "/", filename, " -C ", @install_path, "/"] join
|
116
|
+
output = System pipe: $ ["tar tf ", @download_path, "/", filename] join
|
117
|
+
dirname = output readlines first chomp
|
118
|
+
}
|
119
|
+
|
120
|
+
def installed_path {
|
121
|
+
@install_path + "/" + @user + "_" + @repository + "-" + @version
|
122
|
+
}
|
123
|
+
|
124
|
+
def lib_path {
|
125
|
+
@install_path + "/lib"
|
126
|
+
}
|
127
|
+
|
128
|
+
def rename_dir: dirname {
|
129
|
+
"""
|
130
|
+
Renames a given directory to a common way within the install path.
|
131
|
+
=> It will rename the given dirname to $user/$repo-$version.
|
132
|
+
"""
|
133
|
+
|
134
|
+
System do: $ ["mv ", @install_path, "/", dirname, " ", self installed_path] join
|
135
|
+
}
|
136
|
+
|
137
|
+
def load_fancypack {
|
138
|
+
"""
|
139
|
+
Loads the @.fancypack file within the downloaded package directory.
|
140
|
+
If no @.fancypack file is found, raise an error.
|
141
|
+
"""
|
142
|
+
|
143
|
+
Dir glob(self installed_path ++ "/*.fancypack") first if_do: |fpackfile| {
|
144
|
+
require: fpackfile
|
145
|
+
}
|
146
|
+
|
147
|
+
if: (Specification[@repository]) then: |spec| {
|
148
|
+
fulfill_spec: spec
|
149
|
+
} else: {
|
150
|
+
"Something wen't wrong. Did not find a fancypack specification for package: " ++ @repository . raise!
|
151
|
+
}
|
152
|
+
}
|
153
|
+
|
154
|
+
def fulfill_spec: spec {
|
155
|
+
unless: (spec include_files empty?) do: {
|
156
|
+
File open: (self lib_path + "/" + (spec package_name)) modes: ['write] with: |f| {
|
157
|
+
spec include_files each: |if| {
|
158
|
+
f write: "require: \""
|
159
|
+
f write: (self installed_path)
|
160
|
+
f write: "/"
|
161
|
+
f write: if
|
162
|
+
f writeln: "\""
|
163
|
+
}
|
164
|
+
}
|
165
|
+
}
|
166
|
+
|
167
|
+
spec dependencies each: |dep| {
|
168
|
+
Package install: dep
|
169
|
+
}
|
170
|
+
|
171
|
+
spec rubygem_dependencies each: |dep| {
|
172
|
+
if: (dep version == 'latest) then: {
|
173
|
+
System do: $ "rbx gem install " ++ (dep gem_name)
|
174
|
+
} else: {
|
175
|
+
System do: $ "rbx gem install -v=" ++ (dep version) ++ " " ++ (dep gem_name)
|
176
|
+
}
|
177
|
+
}
|
178
|
+
}
|
179
|
+
}
|
180
|
+
}
|
@@ -0,0 +1,55 @@
|
|
1
|
+
class Fancy Package {
|
2
|
+
class Specification {
|
3
|
+
@@specs = <[]>
|
4
|
+
|
5
|
+
read_write_slots: ['author, 'email, 'include_files, 'bin_files,
|
6
|
+
'description, 'homepage, 'version]
|
7
|
+
|
8
|
+
read_slots: ['package_name, 'dependencies, 'rubygem_dependencies]
|
9
|
+
|
10
|
+
def initialize: @package_name with: block {
|
11
|
+
@dependencies = []
|
12
|
+
@rubygem_dependencies = []
|
13
|
+
@include_files = []
|
14
|
+
@bin_files = []
|
15
|
+
|
16
|
+
block call_with_receiver: self
|
17
|
+
|
18
|
+
@@specs at: @package_name put: self
|
19
|
+
}
|
20
|
+
|
21
|
+
def dependencies: dependencies {
|
22
|
+
dependencies each: |d| {
|
23
|
+
name = d first
|
24
|
+
version = d second
|
25
|
+
{ version = 'latest } unless: version
|
26
|
+
dep = Dependency new: name version: version
|
27
|
+
@dependencies << dep
|
28
|
+
}
|
29
|
+
}
|
30
|
+
|
31
|
+
def ruby_dependencies: dependencies {
|
32
|
+
dependencies each: |d| {
|
33
|
+
gem_name = d first
|
34
|
+
version = d second
|
35
|
+
{ version = 'latest } unless: version
|
36
|
+
dep = RubyDependency new: gem_name version: version
|
37
|
+
@rubygem_dependencies << dep
|
38
|
+
}
|
39
|
+
}
|
40
|
+
|
41
|
+
def add_dependency: name version: version ('latest) {
|
42
|
+
dep = Dependency new: name version: version
|
43
|
+
@dependencies << dep
|
44
|
+
}
|
45
|
+
|
46
|
+
def add_ruby_dependency: gem_name version: version ('latest) {
|
47
|
+
dep = RubyDependency new: gem_name version: version
|
48
|
+
@rubygem_dependencies << dep
|
49
|
+
}
|
50
|
+
|
51
|
+
def self [] package_name {
|
52
|
+
@@specs[package_name]
|
53
|
+
}
|
54
|
+
}
|
55
|
+
}
|
data/lib/parser.fy
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
This directory contains all the code that deals with parsing Fancy
|
2
|
+
source files (.fy) and creating an object-oriented representation (a
|
3
|
+
so-called AST - Abstract Syntax Tree) from it to be used in the
|
4
|
+
compiler for further processing (mostly to .fyc bytecode files).
|
5
|
+
|
6
|
+
The parser.y file contains the grammar rules in GNU Bison (YACC
|
7
|
+
compatible) syntax, which make up the parser. The parser actions are
|
8
|
+
written in C and call out to Ruby methods defined in parser.rb via
|
9
|
+
rbx's C-extension interface to build the actual AST objects.
|
10
|
+
|
11
|
+
The lexer.y contains the lexer rules in GNU Flex syntax for scanning a
|
12
|
+
source file for tokens.
|
13
|
+
|
14
|
+
The parser.rb file contains all the methods used by the parser to
|
15
|
+
create AST objects.
|
@@ -0,0 +1,42 @@
|
|
1
|
+
#include "ext.h"
|
2
|
+
#include "ruby.h"
|
3
|
+
#include "lexer.h"
|
4
|
+
|
5
|
+
static VALUE
|
6
|
+
fancy_parse_string(VALUE self, VALUE code) {
|
7
|
+
VALUE filename = rb_funcall(self, rb_intern(":filename"), 0);
|
8
|
+
VALUE lineno = rb_funcall(self, rb_intern(":line"), 0);
|
9
|
+
char *str = StringValueCStr(code);
|
10
|
+
YY_BUFFER_STATE buffstate = yy_scan_string(str);
|
11
|
+
yy_switch_to_buffer(buffstate);
|
12
|
+
yylineno = NUM2INT(lineno);
|
13
|
+
yyparse(self);
|
14
|
+
yy_delete_buffer(buffstate);
|
15
|
+
return self;
|
16
|
+
}
|
17
|
+
|
18
|
+
static VALUE
|
19
|
+
fancy_parse_file(VALUE self) {
|
20
|
+
VALUE filename = rb_funcall(self, rb_intern(":filename"), 0);
|
21
|
+
VALUE lineno = rb_funcall(self, rb_intern(":line"), 0);
|
22
|
+
char *str = StringValueCStr(filename);
|
23
|
+
FILE *f = fopen(str, "r");
|
24
|
+
if(!f) {
|
25
|
+
rb_funcall(self, rb_intern("ast:file_error:"), 2, INT2NUM(0), rb_str_new2("Could not open file"));
|
26
|
+
return Qnil;
|
27
|
+
}
|
28
|
+
YY_BUFFER_STATE buffstate = yy_create_buffer(f, YY_BUF_SIZE);
|
29
|
+
yy_switch_to_buffer(buffstate);
|
30
|
+
yylineno = NUM2INT(lineno);
|
31
|
+
yyparse(self);
|
32
|
+
yy_delete_buffer(buffstate);
|
33
|
+
return self;
|
34
|
+
}
|
35
|
+
|
36
|
+
void
|
37
|
+
Init_fancy_parser() {
|
38
|
+
VALUE fancy = rb_const_get(rb_cObject, rb_intern("Fancy"));
|
39
|
+
VALUE parser = rb_const_get(fancy, rb_intern("Parser"));
|
40
|
+
rb_define_method(parser, "parse_string:", fancy_parse_string, 1);
|
41
|
+
rb_define_method(parser, ":parse_file", fancy_parse_file, 0);
|
42
|
+
}
|
@@ -0,0 +1,187 @@
|
|
1
|
+
%{
|
2
|
+
#include "ruby.h"
|
3
|
+
#include "parser.h"
|
4
|
+
|
5
|
+
int yyerror(char *s);
|
6
|
+
%}
|
7
|
+
|
8
|
+
%option yylineno
|
9
|
+
|
10
|
+
digit [0-9]
|
11
|
+
octdigit [0-7]
|
12
|
+
hexdigit [0-9a-fA-F]
|
13
|
+
bindigit [01]
|
14
|
+
capital [A-Z]
|
15
|
+
lower [a-z]
|
16
|
+
letter [A-Za-z]
|
17
|
+
special [-+?!=*/^><%&~]
|
18
|
+
special_under ({special}|"_")
|
19
|
+
operator ({special}+|"||"{special_under}*)
|
20
|
+
int_lit [-+]?{digit}({digit}|_{digit})*
|
21
|
+
double_lit {int_lit}\.{digit}+
|
22
|
+
hex_lit 0[xX]{hexdigit}+
|
23
|
+
bin_lit 0[bB]{bindigit}+
|
24
|
+
oct_lit 0[oO]{octdigit}+
|
25
|
+
string_lit L?\"(\\.|[^\\"])*\"
|
26
|
+
multiline_string L?\"\"\"(\\.|[^\\"])*\"\"\"
|
27
|
+
lparen \(
|
28
|
+
rparen \)
|
29
|
+
at_lcurly "@{"
|
30
|
+
lcurly "{"
|
31
|
+
rcurly "}"
|
32
|
+
lbracket "["
|
33
|
+
rbracket "]"
|
34
|
+
lhash "<["
|
35
|
+
rhash "]>"
|
36
|
+
stab "|"
|
37
|
+
arrow "=>"
|
38
|
+
thin_arrow "->"
|
39
|
+
delimiter [ \n\r\t\(\)]
|
40
|
+
return_local "return_local"
|
41
|
+
return "return"
|
42
|
+
require "require:"
|
43
|
+
try "try"
|
44
|
+
catch "catch"
|
45
|
+
finally "finally"
|
46
|
+
retry "retry"
|
47
|
+
super "super"
|
48
|
+
private "private"
|
49
|
+
protected "protected"
|
50
|
+
self "self"
|
51
|
+
match "match"
|
52
|
+
case "case"
|
53
|
+
identifier @?@?({lower}|[_&*])({letter}|{digit}|{special_under})*
|
54
|
+
selector ({letter}|[_&*])({letter}|{digit}|{special_under})*":"
|
55
|
+
constant {capital}({letter}|{digit}|{special_under})*
|
56
|
+
nested_constant ({constant}::)+{constant}
|
57
|
+
symbol_lit \'({identifier}|{operator}|:|"[]")+
|
58
|
+
ruby_send_open {identifier}{lparen}
|
59
|
+
ruby_oper_open {operator}{lparen}
|
60
|
+
regexp_lit "/".*"/"
|
61
|
+
comma ,
|
62
|
+
|
63
|
+
semi ;
|
64
|
+
equals =
|
65
|
+
colon :
|
66
|
+
class "class"
|
67
|
+
def "def"
|
68
|
+
dot "."
|
69
|
+
dollar "$"
|
70
|
+
comment #[^\n]*
|
71
|
+
escaped_newline "\\".*\n
|
72
|
+
|
73
|
+
%%
|
74
|
+
|
75
|
+
{class} { return CLASS; }
|
76
|
+
{def} { return DEF; }
|
77
|
+
{hex_lit} {
|
78
|
+
yylval.object = rb_str_new2(yytext);
|
79
|
+
return HEX_LITERAL;
|
80
|
+
}
|
81
|
+
{oct_lit} {
|
82
|
+
yylval.object = rb_str_new2(yytext);
|
83
|
+
return OCT_LITERAL;
|
84
|
+
}
|
85
|
+
{bin_lit} {
|
86
|
+
yylval.object = rb_str_new2(yytext);
|
87
|
+
return BIN_LITERAL;
|
88
|
+
}
|
89
|
+
{int_lit} {
|
90
|
+
yylval.object = rb_str_new2(yytext);
|
91
|
+
return INTEGER_LITERAL;
|
92
|
+
}
|
93
|
+
{double_lit} {
|
94
|
+
yylval.object = rb_str_new2(yytext);
|
95
|
+
return DOUBLE_LITERAL;
|
96
|
+
}
|
97
|
+
{string_lit} {
|
98
|
+
yylval.object = rb_str_new2(yytext);
|
99
|
+
return STRING_LITERAL;
|
100
|
+
}
|
101
|
+
{multiline_string} {
|
102
|
+
yylval.object = rb_str_new2(yytext);
|
103
|
+
return MULTI_STRING_LITERAL;
|
104
|
+
}
|
105
|
+
{lparen} { return LPAREN; }
|
106
|
+
{rparen} { return RPAREN; }
|
107
|
+
{at_lcurly} { return AT_LCURLY; }
|
108
|
+
{lcurly} { return LCURLY; }
|
109
|
+
{rcurly} { return RCURLY; }
|
110
|
+
{lbracket} { return LBRACKET; }
|
111
|
+
{rbracket} { return RBRACKET; }
|
112
|
+
{lhash} { return LHASH; }
|
113
|
+
{rhash} { return RHASH; }
|
114
|
+
{stab} { return STAB; }
|
115
|
+
{arrow} { return ARROW; }
|
116
|
+
{thin_arrow} { return THIN_ARROW; }
|
117
|
+
{equals} { return EQUALS; }
|
118
|
+
{operator} {
|
119
|
+
yylval.object = rb_str_new2(yytext);
|
120
|
+
return OPERATOR;
|
121
|
+
}
|
122
|
+
{return_local} { return RETURN_LOCAL; }
|
123
|
+
{return} { return RETURN; }
|
124
|
+
{require} { return REQUIRE; }
|
125
|
+
{try} { return TRY; }
|
126
|
+
{catch} { return CATCH; }
|
127
|
+
{finally} { return FINALLY; }
|
128
|
+
{retry} { return RETRY; }
|
129
|
+
{super} { return SUPER; }
|
130
|
+
{private} { return PRIVATE; }
|
131
|
+
{protected} { return PROTECTED; }
|
132
|
+
{self} {
|
133
|
+
yylval.object = rb_str_new2(yytext);
|
134
|
+
return IDENTIFIER;
|
135
|
+
}
|
136
|
+
{match} {
|
137
|
+
return MATCH;
|
138
|
+
}
|
139
|
+
{case} {
|
140
|
+
return CASE;
|
141
|
+
}
|
142
|
+
{identifier} {
|
143
|
+
yylval.object = rb_str_new2(yytext);
|
144
|
+
return IDENTIFIER;
|
145
|
+
}
|
146
|
+
{selector} {
|
147
|
+
yylval.object = rb_str_new2(yytext);
|
148
|
+
return SELECTOR;
|
149
|
+
}
|
150
|
+
{ruby_send_open} {
|
151
|
+
yylval.object = rb_str_new2(yytext);
|
152
|
+
return RUBY_SEND_OPEN;
|
153
|
+
}
|
154
|
+
{ruby_oper_open} {
|
155
|
+
yylval.object = rb_str_new2(yytext);
|
156
|
+
return RUBY_OPER_OPEN;
|
157
|
+
}
|
158
|
+
{constant} {
|
159
|
+
yylval.object = rb_str_new2(yytext);
|
160
|
+
return CONSTANT;
|
161
|
+
}
|
162
|
+
{nested_constant} {
|
163
|
+
yylval.object = rb_str_new2(yytext);
|
164
|
+
return CONSTANT;
|
165
|
+
}
|
166
|
+
{symbol_lit} {
|
167
|
+
yylval.object = rb_str_new2(yytext);
|
168
|
+
return SYMBOL_LITERAL;
|
169
|
+
}
|
170
|
+
{regexp_lit} {
|
171
|
+
yylval.object = rb_str_new2(yytext);
|
172
|
+
return REGEX_LITERAL;
|
173
|
+
}
|
174
|
+
{comma} { return COMMA; }
|
175
|
+
{semi} { return SEMI; }
|
176
|
+
{colon} { return COLON; }
|
177
|
+
{dot} { return DOT; }
|
178
|
+
{dollar} { return DOLLAR; }
|
179
|
+
|
180
|
+
{comment} {}
|
181
|
+
|
182
|
+
[ \t]* {}
|
183
|
+
{escaped_newline} {}
|
184
|
+
[\n] { return NL; }
|
185
|
+
|
186
|
+
. { fprintf(stderr, "SCANNER %d", yyerror("")); exit(1); }
|
187
|
+
|