nilac 0.0.3.3 → 0.0.3.4
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -17
- data/Gemfile +4 -4
- data/LICENSE +21 -21
- data/README.md +37 -13
- data/Rakefile +2 -2
- data/bin/.gitignore +2 -0
- data/bin/{nilac → nilac.rb} +263 -92
- data/examples/sample.js +46 -0
- data/examples/sample.nila +45 -0
- data/lib/nilac/version.rb +1 -1
- data/lib/nilac.rb +5 -5
- data/nilac.gemspec +19 -18
- data/shark/features/add_auto_return_statement.feature +18 -0
- data/shark/features/barebones_compilation.feature +11 -0
- data/shark/features/fix_newlines.feature +13 -0
- data/shark/test_files/correct.js +5 -0
- data/shark/test_files/correct_return.js +9 -0
- data/shark/test_files/correct_single_return.js +9 -0
- data/shark/test_files/erratic.nila +22 -0
- data/shark/test_files/no_return.nila +7 -0
- data/shark/test_files/perfect.js +17 -0
- data/shark/test_files/simple.nila +1 -0
- data/shark/test_files/single_return.nila +7 -0
- metadata +46 -12
- checksums.yaml +0 -7
data/.gitignore
CHANGED
@@ -1,17 +1,17 @@
|
|
1
|
-
*.gem
|
2
|
-
*.rbc
|
3
|
-
.bundle
|
4
|
-
.config
|
5
|
-
.yardoc
|
6
|
-
Gemfile.lock
|
7
|
-
InstalledFiles
|
8
|
-
_yardoc
|
9
|
-
coverage
|
10
|
-
doc/
|
11
|
-
lib/bundler/man
|
12
|
-
pkg
|
13
|
-
rdoc
|
14
|
-
spec/reports
|
15
|
-
test/tmp
|
16
|
-
test/version_tmp
|
17
|
-
tmp
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
data/Gemfile
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
source 'https://rubygems.org'
|
2
|
-
|
3
|
-
# Specify your gem's dependencies in nilac.gemspec
|
4
|
-
gemspec
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
# Specify your gem's dependencies in nilac.gemspec
|
4
|
+
gemspec
|
data/LICENSE
CHANGED
@@ -1,22 +1,22 @@
|
|
1
|
-
Copyright (c) 2013 Adhithya Rajasekaran
|
2
|
-
|
3
|
-
MIT License
|
4
|
-
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
-
a copy of this software and associated documentation files (the
|
7
|
-
"Software"), to deal in the Software without restriction, including
|
8
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
-
permit persons to whom the Software is furnished to do so, subject to
|
11
|
-
the following conditions:
|
12
|
-
|
13
|
-
The above copyright notice and this permission notice shall be
|
14
|
-
included in all copies or substantial portions of the Software.
|
15
|
-
|
16
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
-
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
-
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
-
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
1
|
+
Copyright (c) 2013 Adhithya Rajasekaran
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
22
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
CHANGED
@@ -1,33 +1,45 @@
|
|
1
|
-
#
|
1
|
+
# Nila
|
2
2
|
|
3
|
-
Nilac is the official compiler for the Nila language.
|
3
|
+
Nila is a dialect of Coffeescript with a Rubyspired syntax. Nilac is the official compiler for the Nila language. Nila is still in its infancy and is not suitable for day to day usage.
|
4
4
|
|
5
|
-
##
|
6
|
-
|
7
|
-
Add this line to your application's Gemfile:
|
5
|
+
## Requirements
|
8
6
|
|
9
|
-
|
7
|
+
You will definitely need
|
10
8
|
|
11
|
-
|
9
|
+
* Ruby 2.0 and Rubygems
|
10
|
+
* Node.js with NPM
|
12
11
|
|
13
|
-
|
12
|
+
## Installation
|
14
13
|
|
15
|
-
|
14
|
+
You can install Nila yourself through Rubygems. Just run:
|
16
15
|
|
17
16
|
$ gem install nilac
|
18
17
|
|
19
18
|
## Usage
|
20
19
|
|
21
|
-
Nilac is the official compiler of the Nila language. You can learn more about Nila at http://github.com/adhithyan15/nila.
|
22
|
-
|
23
20
|
To compile your Nila file:
|
24
21
|
|
25
|
-
nilac -c file.nila
|
22
|
+
$ nilac -c file.nila
|
26
23
|
|
27
24
|
To compile and run your Nila file (requires Node.js):
|
28
25
|
|
29
|
-
nilac -r file.nila
|
26
|
+
$ nilac -r file.nila
|
27
|
+
|
28
|
+
## Documentation
|
29
|
+
|
30
|
+
A detailed documentation of the language is available at https://github.com/adhithyan15/nila/wiki/Documentation. Currently, we are working to ship RDoc and Ri based documentation along with the Nilac gem.
|
31
|
+
|
32
|
+
## Tests
|
33
|
+
|
34
|
+
We currently use a homemade micro-testing framework called **Shark** to test our code. You can run tests by calling
|
35
|
+
|
36
|
+
$ Shark -t
|
30
37
|
|
38
|
+
Shark uses Cucumber like syntax and you can read all the tests we have written in the **Shark/features** directory and all the files used in the test are stored in the **Shark/test_files** directory. If you want to know more about Shark, please visit https://github.com/adhithyan15/shark
|
39
|
+
|
40
|
+
## Issues and Bugs
|
41
|
+
|
42
|
+
We utilize Github's issues page to keep track of issues and bugs. You can also post feature requests there. We are trying to close as many issues as possible.
|
31
43
|
|
32
44
|
## Contributing
|
33
45
|
|
@@ -36,3 +48,15 @@ To compile and run your Nila file (requires Node.js):
|
|
36
48
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
37
49
|
4. Push to the branch (`git push origin my-new-feature`)
|
38
50
|
5. Create new Pull Request
|
51
|
+
|
52
|
+
## License
|
53
|
+
|
54
|
+
The project is licensed under MIT License. You can read the legalese below
|
55
|
+
|
56
|
+
Copyright (c) 2013 Adhithya Rajasekaran, Sri Madhavi Rajasekaran
|
57
|
+
|
58
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
59
|
+
|
60
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
61
|
+
|
62
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
#!/usr/bin/env rake
|
2
|
-
require "bundler/gem_tasks"
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
require "bundler/gem_tasks"
|
data/bin/.gitignore
ADDED
data/bin/{nilac → nilac.rb}
RENAMED
@@ -1,14 +1,12 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
1
|
#Nilac is the official Nila compiler. It compiles Nila into pure Javascript. Nilac is currently
|
4
|
-
#written in Ruby but will be self hosted in the upcoming years.
|
5
|
-
#Node.js developers rather than client side developers.
|
2
|
+
#written in Ruby but will be self hosted in the upcoming years.
|
6
3
|
|
7
|
-
#Nila
|
4
|
+
#Nila and Nilac are being crafted by Adhithya Rajasekaran and Sri Madhavi Rajasekaran
|
8
5
|
|
9
|
-
require '
|
6
|
+
require 'slop'
|
7
|
+
require 'fileutils'
|
10
8
|
|
11
|
-
def compile(input_file_path)
|
9
|
+
def compile(input_file_path,*output_file_name)
|
12
10
|
|
13
11
|
def read_file_line_by_line(input_path)
|
14
12
|
|
@@ -28,17 +26,25 @@ def compile(input_file_path)
|
|
28
26
|
|
29
27
|
line_counter = 0
|
30
28
|
|
31
|
-
|
29
|
+
if input_file_contents.join.include?("__END__")
|
32
30
|
|
33
|
-
line_counter
|
31
|
+
while !reversed_file_contents[line_counter].strip.include?("__END__")
|
34
32
|
|
35
|
-
|
33
|
+
line_counter += 1
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
return_contents = input_file_contents[0...-1*line_counter-1]
|
36
38
|
|
37
|
-
|
39
|
+
else
|
40
|
+
|
41
|
+
input_file_contents
|
42
|
+
|
43
|
+
end
|
38
44
|
|
39
45
|
end
|
40
46
|
|
41
|
-
def replace_multiline_comments(input_file_contents,nila_file_path)
|
47
|
+
def replace_multiline_comments(input_file_contents,nila_file_path,*output_js_file_path)
|
42
48
|
|
43
49
|
#This method will replace both the single and multiline comments
|
44
50
|
#
|
@@ -125,7 +131,15 @@ def compile(input_file_path)
|
|
125
131
|
|
126
132
|
temporary_nila_file = find_file_path(nila_file_path,".nila") + "temp_nila.nila"
|
127
133
|
|
128
|
-
|
134
|
+
if output_js_file_path.empty?
|
135
|
+
|
136
|
+
output_js_file = find_file_path(nila_file_path,".nila") + find_file_name(nila_file_path,".nila") + ".js"
|
137
|
+
|
138
|
+
else
|
139
|
+
|
140
|
+
output_js_file = output_js_file_path[0]
|
141
|
+
|
142
|
+
end
|
129
143
|
|
130
144
|
file_id = open(temporary_nila_file, 'w')
|
131
145
|
|
@@ -133,8 +147,6 @@ def compile(input_file_path)
|
|
133
147
|
|
134
148
|
file_id.write(modified_file_contents)
|
135
149
|
|
136
|
-
file_id2.write("//Written in Nila and compiled to Javascript. Have fun!\n\n")
|
137
|
-
|
138
150
|
file_id.close()
|
139
151
|
|
140
152
|
file_id2.close()
|
@@ -416,7 +428,7 @@ def compile(input_file_path)
|
|
416
428
|
|
417
429
|
#The condition below verifies if the rows contain any equation operators.
|
418
430
|
|
419
|
-
if current_row.include?("=")
|
431
|
+
if current_row.include?("=") and !current_row.include?("def")
|
420
432
|
|
421
433
|
current_row = current_row.rstrip + "\n"
|
422
434
|
|
@@ -589,7 +601,7 @@ def compile(input_file_path)
|
|
589
601
|
|
590
602
|
#def square(input_number)
|
591
603
|
#
|
592
|
-
#
|
604
|
+
# input_number*input_number
|
593
605
|
#
|
594
606
|
#end
|
595
607
|
|
@@ -624,7 +636,7 @@ def compile(input_file_path)
|
|
624
636
|
|
625
637
|
input_function_block.each do |line|
|
626
638
|
|
627
|
-
if line.include? "="
|
639
|
+
if line.include? "=" and !line.include?("def")
|
628
640
|
|
629
641
|
current_line_split = line.strip.split("=")
|
630
642
|
|
@@ -672,7 +684,9 @@ def compile(input_file_path)
|
|
672
684
|
|
673
685
|
if !joined_array.include?("return ")
|
674
686
|
|
675
|
-
rejected_array = reversed_input_array.reject {|content| content.
|
687
|
+
rejected_array = reversed_input_array.reject {|content| content.lstrip.eql?("")}
|
688
|
+
|
689
|
+
rejected_array = rejected_array.reject {|content| content.strip.eql? "}"}
|
676
690
|
|
677
691
|
last_statement = rejected_array[0]
|
678
692
|
|
@@ -828,8 +842,6 @@ def compile(input_file_path)
|
|
828
842
|
|
829
843
|
def compile_custom_function_map(input_file_contents)
|
830
844
|
|
831
|
-
function_map = ["puts","print"]
|
832
|
-
|
833
845
|
function_map_replacements = {
|
834
846
|
|
835
847
|
"puts" => "console.log",
|
@@ -838,6 +850,8 @@ def compile(input_file_path)
|
|
838
850
|
|
839
851
|
}
|
840
852
|
|
853
|
+
function_map = function_map_replacements.keys
|
854
|
+
|
841
855
|
modified_file_contents = input_file_contents.dup
|
842
856
|
|
843
857
|
input_file_contents.each_with_index do |line,index|
|
@@ -894,11 +908,12 @@ def compile(input_file_path)
|
|
894
908
|
|
895
909
|
end
|
896
910
|
|
897
|
-
|
898
911
|
return pattern
|
899
912
|
|
900
913
|
end
|
901
914
|
|
915
|
+
input_file_contents[-1] = input_file_contents[-1] + "\n" if !input_file_contents[-1].include?("\n")
|
916
|
+
|
902
917
|
joined_file_contents = input_file_contents.join
|
903
918
|
|
904
919
|
function_names.each do |list_of_functions|
|
@@ -939,7 +954,7 @@ def compile(input_file_path)
|
|
939
954
|
|
940
955
|
#Currently the following conditional structures have been implemented
|
941
956
|
|
942
|
-
#1. If
|
957
|
+
#1. If and While Inline Statements
|
943
958
|
|
944
959
|
def compile_inline_conditionals(input_file_contents,temporary_nila_file)
|
945
960
|
|
@@ -1075,7 +1090,7 @@ def compile(input_file_path)
|
|
1075
1090
|
|
1076
1091
|
if !comment(line)
|
1077
1092
|
|
1078
|
-
if !line.eql?("
|
1093
|
+
if !line.lstrip.eql?("")
|
1079
1094
|
|
1080
1095
|
if !line.lstrip.eql?("}\n")
|
1081
1096
|
|
@@ -1195,6 +1210,95 @@ def compile(input_file_path)
|
|
1195
1210
|
|
1196
1211
|
end
|
1197
1212
|
|
1213
|
+
def fix_newlines(file_contents)
|
1214
|
+
|
1215
|
+
def extract_blocks(file_contents)
|
1216
|
+
|
1217
|
+
javascript_regexp = /(if |while |function |function\()/
|
1218
|
+
|
1219
|
+
block_starting_lines = file_contents.dup.reject { |element| element.index(javascript_regexp).nil?}[1..-1]
|
1220
|
+
|
1221
|
+
block_starting_lines = block_starting_lines.reject { |element| element.include?(" ")}
|
1222
|
+
|
1223
|
+
initial_starting_lines = block_starting_lines.dup
|
1224
|
+
|
1225
|
+
starting_line_indices = []
|
1226
|
+
|
1227
|
+
block_starting_lines.each do |line|
|
1228
|
+
|
1229
|
+
starting_line_indices << file_contents.index(line)
|
1230
|
+
|
1231
|
+
end
|
1232
|
+
|
1233
|
+
block_ending_lines = file_contents.dup.each_index.select { |index| file_contents[index].eql? " }\n" }
|
1234
|
+
|
1235
|
+
modified_file_contents = file_contents.dup
|
1236
|
+
|
1237
|
+
code_blocks = []
|
1238
|
+
|
1239
|
+
starting_index = starting_line_indices[0]
|
1240
|
+
|
1241
|
+
for x in 0...initial_starting_lines.length
|
1242
|
+
|
1243
|
+
code_blocks << modified_file_contents[starting_index..block_ending_lines[0]]
|
1244
|
+
|
1245
|
+
modified_file_contents[starting_index..block_ending_lines[0]] = []
|
1246
|
+
|
1247
|
+
modified_file_contents.insert(starting_index," *****")
|
1248
|
+
|
1249
|
+
block_starting_lines = modified_file_contents.dup.reject { |element| element.index(javascript_regexp).nil?}[1..-1]
|
1250
|
+
|
1251
|
+
block_starting_lines = block_starting_lines.reject { |element| element.include?(" ")}
|
1252
|
+
|
1253
|
+
starting_line_indices = []
|
1254
|
+
|
1255
|
+
block_starting_lines.each do |line|
|
1256
|
+
|
1257
|
+
starting_line_indices << modified_file_contents.index(line)
|
1258
|
+
|
1259
|
+
end
|
1260
|
+
|
1261
|
+
block_ending_lines = modified_file_contents.dup.each_index.select { |index| modified_file_contents[index].eql? " }\n" }
|
1262
|
+
|
1263
|
+
starting_index = starting_line_indices[0]
|
1264
|
+
|
1265
|
+
end
|
1266
|
+
|
1267
|
+
return modified_file_contents,code_blocks
|
1268
|
+
|
1269
|
+
end
|
1270
|
+
|
1271
|
+
compact_contents = file_contents.reject {|element| element.lstrip.eql? ""}
|
1272
|
+
|
1273
|
+
compact_contents,code_blocks = extract_blocks(compact_contents)
|
1274
|
+
|
1275
|
+
processed_contents = compact_contents[1...-1].collect {|line| line+"\n"}
|
1276
|
+
|
1277
|
+
compact_contents = [compact_contents[0]] + processed_contents + [compact_contents[-1]]
|
1278
|
+
|
1279
|
+
code_block_locations = compact_contents.each_index.select { |index| compact_contents[index].eql? " *****\n"}
|
1280
|
+
|
1281
|
+
initial_locations = code_block_locations.dup
|
1282
|
+
|
1283
|
+
starting_index = code_block_locations[0]
|
1284
|
+
|
1285
|
+
for x in 0...initial_locations.length
|
1286
|
+
|
1287
|
+
code_blocks[x][-1] = code_blocks[x][-1] + "\n"
|
1288
|
+
|
1289
|
+
compact_contents = compact_contents[0...starting_index] + code_blocks[x] + compact_contents[starting_index+1..-1]
|
1290
|
+
|
1291
|
+
code_block_locations = compact_contents.each_index.select { |index| compact_contents[index].eql? " *****\n"}
|
1292
|
+
|
1293
|
+
starting_index = code_block_locations[0]
|
1294
|
+
|
1295
|
+
|
1296
|
+
end
|
1297
|
+
|
1298
|
+
return compact_contents
|
1299
|
+
|
1300
|
+
end
|
1301
|
+
|
1198
1302
|
javascript_regexp = /(if |while |function |function\()/
|
1199
1303
|
|
1200
1304
|
locations = []
|
@@ -1261,7 +1365,17 @@ def compile(input_file_path)
|
|
1261
1365
|
|
1262
1366
|
nested_indices.each_with_index do |loc,index|
|
1263
1367
|
|
1264
|
-
|
1368
|
+
begin
|
1369
|
+
|
1370
|
+
locations[loc-1] << nested_elements[index]
|
1371
|
+
|
1372
|
+
rescue NoMethodError
|
1373
|
+
|
1374
|
+
puts "The pretty printing process exited with errors!"
|
1375
|
+
|
1376
|
+
end
|
1377
|
+
|
1378
|
+
|
1265
1379
|
|
1266
1380
|
end
|
1267
1381
|
|
@@ -1325,6 +1439,8 @@ def compile(input_file_path)
|
|
1325
1439
|
|
1326
1440
|
line_by_line_contents = read_file_line_by_line(temporary_nila_file)
|
1327
1441
|
|
1442
|
+
line_by_line_contents = fix_newlines(line_by_line_contents)
|
1443
|
+
|
1328
1444
|
return line_by_line_contents
|
1329
1445
|
|
1330
1446
|
end
|
@@ -1346,7 +1462,7 @@ def compile(input_file_path)
|
|
1346
1462
|
# A feature imported from Coffeescript. This makes all the function private by default
|
1347
1463
|
# and prevents global variables from leaking.
|
1348
1464
|
|
1349
|
-
modified_file_contents = ["(function() {\n
|
1465
|
+
modified_file_contents = ["(function() {\n",input_file_contents,"\n}).call(this);"].flatten
|
1350
1466
|
|
1351
1467
|
return modified_file_contents
|
1352
1468
|
|
@@ -1358,9 +1474,7 @@ def compile(input_file_path)
|
|
1358
1474
|
|
1359
1475
|
File.delete(temporary_nila_file)
|
1360
1476
|
|
1361
|
-
file_id.write("//Written in Nila
|
1362
|
-
|
1363
|
-
file_id.write("//Visit http://adhithyan15.github.com/nila to know more!\n\n")
|
1477
|
+
file_id.write("//Written in Nila 0.0.3.2. Visit http://adhithyan15.github.io/nila\n")
|
1364
1478
|
|
1365
1479
|
file_id.write(file_contents.join)
|
1366
1480
|
|
@@ -1368,67 +1482,58 @@ def compile(input_file_path)
|
|
1368
1482
|
|
1369
1483
|
end
|
1370
1484
|
|
1371
|
-
|
1372
|
-
|
1373
|
-
file_contents = extract_parsable_file(file_contents)
|
1485
|
+
if File.exist?(input_file_path)
|
1374
1486
|
|
1375
|
-
|
1487
|
+
file_contents = read_file_line_by_line(input_file_path)
|
1376
1488
|
|
1377
|
-
|
1489
|
+
file_contents = extract_parsable_file(file_contents)
|
1378
1490
|
|
1379
|
-
|
1491
|
+
file_contents,multiline_comments,temp_file,output_js_file = replace_multiline_comments(file_contents,input_file_path,*output_file_name)
|
1380
1492
|
|
1381
|
-
|
1493
|
+
file_contents = split_semicolon_seperated_expressions(file_contents)
|
1382
1494
|
|
1383
|
-
|
1495
|
+
file_contents = compile_interpolated_strings(file_contents)
|
1384
1496
|
|
1385
|
-
|
1497
|
+
file_contents,singleline_comments = replace_singleline_comments(file_contents)
|
1386
1498
|
|
1387
|
-
|
1499
|
+
file_contents,named_functions,nested_functions = replace_named_functions(file_contents,temp_file)
|
1388
1500
|
|
1389
|
-
|
1501
|
+
comments = [singleline_comments,multiline_comments]
|
1390
1502
|
|
1391
|
-
|
1503
|
+
list_of_variables,file_contents = get_variables(file_contents,temp_file)
|
1392
1504
|
|
1393
|
-
|
1505
|
+
file_contents = compile_arrays(file_contents)
|
1394
1506
|
|
1395
|
-
|
1507
|
+
file_contents = compile_conditional_structures(file_contents,temp_file)
|
1396
1508
|
|
1397
|
-
|
1509
|
+
file_contents, function_names = compile_named_functions(file_contents,named_functions,nested_functions,temp_file)
|
1398
1510
|
|
1399
|
-
|
1511
|
+
file_contents, ruby_functions = compile_custom_function_map(file_contents)
|
1400
1512
|
|
1401
|
-
|
1513
|
+
function_names << ruby_functions
|
1402
1514
|
|
1403
|
-
|
1515
|
+
file_contents = compile_whitespace_delimited_functions(file_contents,function_names,temp_file)
|
1404
1516
|
|
1405
|
-
|
1517
|
+
file_contents = remove_question_marks(file_contents,list_of_variables,temp_file)
|
1406
1518
|
|
1407
|
-
|
1519
|
+
file_contents = add_semicolons(file_contents)
|
1408
1520
|
|
1409
|
-
|
1410
|
-
|
1411
|
-
output_javascript(file_contents,output_js_file,temp_file)
|
1412
|
-
|
1413
|
-
|
1414
|
-
end
|
1521
|
+
file_contents = compile_comments(file_contents,comments,temp_file)
|
1415
1522
|
|
1416
|
-
|
1523
|
+
file_contents = create_self_invoking_function(file_contents)
|
1417
1524
|
|
1418
|
-
|
1525
|
+
file_contents = pretty_print_javascript(file_contents,temp_file)
|
1419
1526
|
|
1420
|
-
|
1527
|
+
output_javascript(file_contents,output_js_file,temp_file)
|
1421
1528
|
|
1422
|
-
|
1529
|
+
puts "Compilation is successful!"
|
1423
1530
|
|
1424
|
-
|
1531
|
+
else
|
1425
1532
|
|
1426
|
-
|
1533
|
+
puts "File doesn't exist!"
|
1427
1534
|
|
1428
1535
|
end
|
1429
1536
|
|
1430
|
-
windows_output = `ocra --add-all-core #{input_file}`
|
1431
|
-
|
1432
1537
|
end
|
1433
1538
|
|
1434
1539
|
def create_mac_executable(input_file)
|
@@ -1445,7 +1550,7 @@ def create_mac_executable(input_file)
|
|
1445
1550
|
|
1446
1551
|
end
|
1447
1552
|
|
1448
|
-
mac_file_contents = ["#!/usr/bin/env ruby
|
1553
|
+
mac_file_contents = ["#!/usr/bin/env ruby"] + read_file_line_by_line(input_file)
|
1449
1554
|
|
1450
1555
|
mac_file_path = input_file.sub(".rb","")
|
1451
1556
|
|
@@ -1463,7 +1568,7 @@ def find_file_name(input_path,file_extension)
|
|
1463
1568
|
|
1464
1569
|
remaining_string = extension_remover[0].reverse
|
1465
1570
|
|
1466
|
-
path_finder = remaining_string.index("
|
1571
|
+
path_finder = remaining_string.index("/")
|
1467
1572
|
|
1468
1573
|
remaining_string = remaining_string.reverse
|
1469
1574
|
|
@@ -1471,52 +1576,118 @@ def find_file_name(input_path,file_extension)
|
|
1471
1576
|
|
1472
1577
|
end
|
1473
1578
|
|
1474
|
-
|
1579
|
+
opts = Slop.parse do
|
1580
|
+
on :c, :compile=, 'Compile Nila File', as:Array, delimiter:":"
|
1581
|
+
on :r, :run=, 'Run Nila File', as:Array
|
1582
|
+
on :m, :buildmac=, 'Build Nilac for Linux/Mac/Rubygems',as:Array
|
1583
|
+
end
|
1475
1584
|
|
1476
|
-
|
1477
|
-
opts.banner = "Usage: nilac [options] nilafile"
|
1585
|
+
opts = opts.to_hash
|
1478
1586
|
|
1479
|
-
|
1480
|
-
current_directory = Dir.pwd
|
1481
|
-
file_path = current_directory + "/" + file
|
1482
|
-
compile(file_path)
|
1483
|
-
puts "Compilation Successful!"
|
1587
|
+
if opts[:compile] != nil
|
1484
1588
|
|
1485
|
-
|
1589
|
+
if opts[:compile].length == 1
|
1486
1590
|
|
1487
|
-
|
1488
|
-
current_directory = Dir.pwd
|
1591
|
+
input = opts[:compile][0]
|
1489
1592
|
|
1490
|
-
|
1593
|
+
if input.include? ".nila"
|
1491
1594
|
|
1492
|
-
|
1595
|
+
current_directory = Dir.pwd
|
1493
1596
|
|
1494
|
-
|
1597
|
+
input_file = input
|
1495
1598
|
|
1496
|
-
|
1599
|
+
file_path = current_directory + "/" + input_file
|
1497
1600
|
|
1498
|
-
|
1601
|
+
compile(file_path)
|
1499
1602
|
|
1500
|
-
|
1603
|
+
elsif input.include? "/"
|
1501
1604
|
|
1502
|
-
|
1605
|
+
folder_path = input
|
1503
1606
|
|
1504
|
-
|
1607
|
+
files = Dir.glob(File.join(folder_path, "*"))
|
1505
1608
|
|
1506
|
-
|
1609
|
+
files = files.reject {|path| !path.include? ".nila"}
|
1507
1610
|
|
1508
|
-
|
1611
|
+
files.each do |file|
|
1509
1612
|
|
1510
|
-
|
1613
|
+
file_path = Dir.pwd + "/" + file
|
1614
|
+
|
1615
|
+
compile(file_path)
|
1616
|
+
|
1617
|
+
end
|
1618
|
+
|
1619
|
+
end
|
1620
|
+
|
1621
|
+
elsif opts[:compile].length == 2
|
1622
|
+
|
1623
|
+
input = opts[:compile][0]
|
1511
1624
|
|
1512
|
-
|
1625
|
+
output = opts[:compile][1]
|
1513
1626
|
|
1514
|
-
|
1627
|
+
if input.include? ".nila" and output.include? ".js"
|
1515
1628
|
|
1516
|
-
|
1629
|
+
input_file = input
|
1517
1630
|
|
1518
|
-
|
1631
|
+
output_file = output
|
1632
|
+
|
1633
|
+
input_file_path = input_file
|
1634
|
+
|
1635
|
+
output_file_path = output_file
|
1636
|
+
|
1637
|
+
compile(input_file_path,output_file_path)
|
1638
|
+
|
1639
|
+
elsif input[-1].eql? "/" and output[-1].eql? "/"
|
1640
|
+
|
1641
|
+
input_folder_path = input
|
1642
|
+
|
1643
|
+
output_folder_path = output
|
1644
|
+
|
1645
|
+
if !File.directory?(output_folder_path)
|
1646
|
+
|
1647
|
+
FileUtils.mkdir_p(output_folder_path)
|
1648
|
+
|
1649
|
+
end
|
1650
|
+
|
1651
|
+
files = Dir.glob(File.join(input_folder_path, "*"))
|
1652
|
+
|
1653
|
+
files = files.reject {|path| !path.include? ".nila"}
|
1654
|
+
|
1655
|
+
files.each do |file|
|
1656
|
+
|
1657
|
+
input_file_path = file
|
1658
|
+
|
1659
|
+
output_file_path = output_folder_path + find_file_name(file,".nila") + ".js"
|
1660
|
+
|
1661
|
+
compile(input_file_path,output_file_path)
|
1662
|
+
|
1663
|
+
end
|
1664
|
+
|
1665
|
+
end
|
1519
1666
|
|
1520
1667
|
end
|
1521
1668
|
|
1522
|
-
|
1669
|
+
elsif opts[:run] != nil
|
1670
|
+
|
1671
|
+
current_directory = Dir.pwd
|
1672
|
+
|
1673
|
+
file = opts[:run][0]
|
1674
|
+
|
1675
|
+
file_path = current_directory + "/" + file
|
1676
|
+
|
1677
|
+
compile(file_path)
|
1678
|
+
|
1679
|
+
js_file_name = find_file_name(file_path,".nila") + ".js"
|
1680
|
+
|
1681
|
+
node_output = `node #{js_file_name}`
|
1682
|
+
|
1683
|
+
puts node_output
|
1684
|
+
|
1685
|
+
elsif opts[:buildmac] != nil
|
1686
|
+
|
1687
|
+
file_path = Dir.pwd + "/bin/nilac.rb"
|
1688
|
+
|
1689
|
+
create_mac_executable(file_path)
|
1690
|
+
|
1691
|
+
puts "Build Successful!"
|
1692
|
+
|
1693
|
+
end
|
data/examples/sample.js
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
//Written in Nila 0.0.3.2. Visit http://adhithyan15.github.io/nila
|
2
|
+
(function() {
|
3
|
+
var hello, msg, message, goal_reached, isprime, visitor_present, names;
|
4
|
+
|
5
|
+
hello = "world";
|
6
|
+
|
7
|
+
msg = "Nila";
|
8
|
+
|
9
|
+
message = "Welcome to " + msg;
|
10
|
+
|
11
|
+
goal_reached = 72;
|
12
|
+
|
13
|
+
isprime = false;
|
14
|
+
|
15
|
+
visitor_present = true;
|
16
|
+
|
17
|
+
if (visitor_present) {
|
18
|
+
console.log("Hello Visitor!");
|
19
|
+
}
|
20
|
+
|
21
|
+
names = ["adhi", "alex", "john", "bill", "kelly"];
|
22
|
+
|
23
|
+
function printsquare(input_number) {
|
24
|
+
//This is a very simple Nila function
|
25
|
+
var add_number, isvalid;
|
26
|
+
add_number = input_number + 10;
|
27
|
+
isvalid = true;
|
28
|
+
function square(number) {
|
29
|
+
return number*number;
|
30
|
+
}
|
31
|
+
return console.log("Square of " + add_number + " is " + square(add_number));
|
32
|
+
}
|
33
|
+
|
34
|
+
console.log(printsquare(5));
|
35
|
+
|
36
|
+
function test_message() {
|
37
|
+
return console.log("Welcome to Nila!");
|
38
|
+
}
|
39
|
+
|
40
|
+
function welcome_message() {
|
41
|
+
return console.log("Welcome to Nila!");
|
42
|
+
}
|
43
|
+
|
44
|
+
console.log(welcome_message);
|
45
|
+
|
46
|
+
}).call(this);
|
@@ -0,0 +1,45 @@
|
|
1
|
+
hello = "world";msg = "Nila"
|
2
|
+
|
3
|
+
message = "Welcome to #{msg}"
|
4
|
+
|
5
|
+
goal_reached = 72
|
6
|
+
|
7
|
+
isprime? = false
|
8
|
+
|
9
|
+
visitor_present? = true
|
10
|
+
|
11
|
+
puts("Hello Visitor!") if visitor_present?
|
12
|
+
|
13
|
+
names = %w{adhi alex john bill kelly}
|
14
|
+
|
15
|
+
def printsquare(input_number) #This is a very simple Nila function
|
16
|
+
|
17
|
+
add_number = input_number + 10
|
18
|
+
|
19
|
+
isvalid? = true
|
20
|
+
|
21
|
+
def square(number)
|
22
|
+
|
23
|
+
number*number
|
24
|
+
|
25
|
+
end
|
26
|
+
|
27
|
+
puts "Square of #{add_number} is #{square(add_number)}"
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
puts(printsquare(5))
|
32
|
+
|
33
|
+
def test_message
|
34
|
+
|
35
|
+
puts "Welcome to Nila!"
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
def welcome_message
|
40
|
+
|
41
|
+
puts "Welcome to Nila!"
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
puts welcome_message
|
data/lib/nilac/version.rb
CHANGED
data/lib/nilac.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
require "nilac/version"
|
2
|
-
|
3
|
-
module Nilac
|
4
|
-
|
5
|
-
end
|
1
|
+
require "nilac/version"
|
2
|
+
|
3
|
+
module Nilac
|
4
|
+
|
5
|
+
end
|
data/nilac.gemspec
CHANGED
@@ -1,18 +1,19 @@
|
|
1
|
-
# -*- encoding: utf-8 -*-
|
2
|
-
require File.expand_path('../lib/nilac/version', __FILE__)
|
3
|
-
|
4
|
-
Gem::Specification.new do |gem|
|
5
|
-
gem.authors = ["Adhithya Rajasekaran"]
|
6
|
-
gem.email = ["adhithyan15@gmail.com"]
|
7
|
-
gem.description = %q{Nilac is the official compiler of Nila language}
|
8
|
-
gem.summary = %q{Nilac compiles Nila files into line for line Javascript.}
|
9
|
-
gem.homepage = "http://adhithyan15.github.com/nila"
|
10
|
-
|
11
|
-
gem.files = `git ls-files`.split($\)
|
12
|
-
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
-
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
-
gem.name = "nilac"
|
15
|
-
gem.require_paths = ["lib"]
|
16
|
-
gem.version = Nilac::VERSION
|
17
|
-
gem.add_dependency("shark")
|
18
|
-
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/nilac/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Adhithya Rajasekaran"]
|
6
|
+
gem.email = ["adhithyan15@gmail.com"]
|
7
|
+
gem.description = %q{Nilac is the official compiler of Nila language}
|
8
|
+
gem.summary = %q{Nilac compiles Nila files into line for line Javascript.}
|
9
|
+
gem.homepage = "http://adhithyan15.github.com/nila"
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "nilac"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = Nilac::VERSION
|
17
|
+
gem.add_dependency("shark")
|
18
|
+
gem.add_dependency("slop")
|
19
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
Feature: Adding automatic return statements to the last evaluated statement
|
2
|
+
in a function. It is a rubyesque feature imported into Nila.
|
3
|
+
Scenario: Input function with no return statement
|
4
|
+
Given the input file "no_return.nila"
|
5
|
+
When the ~compiler is run
|
6
|
+
The output file must be "no_return.js"
|
7
|
+
The output file must equal "correct_return.js"
|
8
|
+
|
9
|
+
Scenario: Input function with a return statement
|
10
|
+
Given the input file "single_return.nila"
|
11
|
+
When the ~compiler is run
|
12
|
+
The output file must be "single_return.js"
|
13
|
+
The output file must equal "correct_single_return.js"
|
14
|
+
|
15
|
+
Configurations:
|
16
|
+
|
17
|
+
~compiler => bin/nilac.rb
|
18
|
+
:v $cliusage => ruby :v --compile $file
|
@@ -0,0 +1,11 @@
|
|
1
|
+
Feature: Compiling a single line nila program
|
2
|
+
Scenario: Input with a single line nila program
|
3
|
+
Given the input file "simple.nila"
|
4
|
+
When the ~compiler is run
|
5
|
+
The output file must be "simple.js"
|
6
|
+
The output file must equal "correct.js"
|
7
|
+
|
8
|
+
Configurations:
|
9
|
+
|
10
|
+
~compiler => bin/nilac.rb
|
11
|
+
:v $cliusage => ruby :v --compile $file
|
@@ -0,0 +1,13 @@
|
|
1
|
+
Feature: Fixing irregular newlines produced in the Javascript output.
|
2
|
+
Currently, The output Javascript is riddled with unnecessary newlines
|
3
|
+
which will make it fail in a JSLint test.
|
4
|
+
Scenario: Input with erratic newlines
|
5
|
+
Given the input file "erratic.nila"
|
6
|
+
When the ~compiler is run
|
7
|
+
The output file must be "erratic.js"
|
8
|
+
The output file must equal "perfect.js"
|
9
|
+
|
10
|
+
Configurations:
|
11
|
+
|
12
|
+
~compiler => bin/nilac.rb
|
13
|
+
:v $cliusage => ruby :v --compile $file
|
@@ -0,0 +1,17 @@
|
|
1
|
+
//Written in Nila 0.0.3.2. Visit http://adhithyan15.github.io/nila
|
2
|
+
(function() {
|
3
|
+
var hello, msg, message, goal_reached;
|
4
|
+
|
5
|
+
hello = "world";
|
6
|
+
|
7
|
+
msg = "nila";
|
8
|
+
|
9
|
+
message = "Welcome to " + msg;
|
10
|
+
|
11
|
+
goal_reached = 72;
|
12
|
+
|
13
|
+
function square(inputnumber) {
|
14
|
+
return inputnumber*inputnumber;
|
15
|
+
}
|
16
|
+
|
17
|
+
}).call(this);
|
@@ -0,0 +1 @@
|
|
1
|
+
puts "Hello World!"
|
metadata
CHANGED
@@ -1,34 +1,54 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nilac
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.3.
|
4
|
+
version: 0.0.3.4
|
5
|
+
prerelease:
|
5
6
|
platform: ruby
|
6
7
|
authors:
|
7
8
|
- Adhithya Rajasekaran
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date: 2013-06-
|
12
|
+
date: 2013-06-23 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: shark
|
15
16
|
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
16
18
|
requirements:
|
17
|
-
- - '>='
|
19
|
+
- - ! '>='
|
18
20
|
- !ruby/object:Gem::Version
|
19
21
|
version: '0'
|
20
22
|
type: :runtime
|
21
23
|
prerelease: false
|
22
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
23
26
|
requirements:
|
24
|
-
- - '>='
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: slop
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
25
44
|
- !ruby/object:Gem::Version
|
26
45
|
version: '0'
|
27
46
|
description: Nilac is the official compiler of Nila language
|
28
47
|
email:
|
29
48
|
- adhithyan15@gmail.com
|
30
49
|
executables:
|
31
|
-
-
|
50
|
+
- .gitignore
|
51
|
+
- nilac.rb
|
32
52
|
extensions: []
|
33
53
|
extra_rdoc_files: []
|
34
54
|
files:
|
@@ -37,32 +57,46 @@ files:
|
|
37
57
|
- LICENSE
|
38
58
|
- README.md
|
39
59
|
- Rakefile
|
40
|
-
- bin
|
60
|
+
- bin/.gitignore
|
61
|
+
- bin/nilac.rb
|
62
|
+
- examples/sample.js
|
63
|
+
- examples/sample.nila
|
41
64
|
- lib/nilac.rb
|
42
65
|
- lib/nilac/version.rb
|
43
66
|
- nilac.gemspec
|
67
|
+
- shark/features/add_auto_return_statement.feature
|
68
|
+
- shark/features/barebones_compilation.feature
|
69
|
+
- shark/features/fix_newlines.feature
|
70
|
+
- shark/test_files/correct.js
|
71
|
+
- shark/test_files/correct_return.js
|
72
|
+
- shark/test_files/correct_single_return.js
|
73
|
+
- shark/test_files/erratic.nila
|
74
|
+
- shark/test_files/no_return.nila
|
75
|
+
- shark/test_files/perfect.js
|
76
|
+
- shark/test_files/simple.nila
|
77
|
+
- shark/test_files/single_return.nila
|
44
78
|
homepage: http://adhithyan15.github.com/nila
|
45
79
|
licenses: []
|
46
|
-
metadata: {}
|
47
80
|
post_install_message:
|
48
81
|
rdoc_options: []
|
49
82
|
require_paths:
|
50
83
|
- lib
|
51
84
|
required_ruby_version: !ruby/object:Gem::Requirement
|
85
|
+
none: false
|
52
86
|
requirements:
|
53
|
-
- - '>='
|
87
|
+
- - ! '>='
|
54
88
|
- !ruby/object:Gem::Version
|
55
89
|
version: '0'
|
56
90
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
91
|
+
none: false
|
57
92
|
requirements:
|
58
|
-
- - '>='
|
93
|
+
- - ! '>='
|
59
94
|
- !ruby/object:Gem::Version
|
60
95
|
version: '0'
|
61
96
|
requirements: []
|
62
97
|
rubyforge_project:
|
63
|
-
rubygems_version:
|
98
|
+
rubygems_version: 1.8.24
|
64
99
|
signing_key:
|
65
|
-
specification_version:
|
100
|
+
specification_version: 3
|
66
101
|
summary: Nilac compiles Nila files into line for line Javascript.
|
67
102
|
test_files: []
|
68
|
-
has_rdoc:
|
checksums.yaml
DELETED
@@ -1,7 +0,0 @@
|
|
1
|
-
---
|
2
|
-
SHA1:
|
3
|
-
metadata.gz: 913aa385589083183907dcb33f145a1bd5e952b2
|
4
|
-
data.tar.gz: bf2b9549fd19946a5ce8f91c9e45f57717c99801
|
5
|
-
SHA512:
|
6
|
-
metadata.gz: 42cdce137f9333024bd4e943567185cc4e50e4cc775beb8ab90e2b3c57835f06ba6bfc25dedf4bfe63c54be48b69ee554b9c45d14b0659a8e886d5ce6c143b01
|
7
|
-
data.tar.gz: c84df5076f09626f9e8a77a9e0b7f1f4d2b912baaeecb9a222e5e836abfd96a6e2c15874b00e1c6df22b49f57245bb80bb15f61f312a470ccb35aff5c62113b9
|