nilac 0.0.3.4 → 0.0.3.5
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/bin/nilac +1693 -0
- data/lib/nilac/version.rb +1 -1
- metadata +4 -2
data/bin/nilac
ADDED
@@ -0,0 +1,1693 @@
|
|
1
|
+
#!/usr/bin/env ruby#Nilac is the official Nila compiler. It compiles Nila into pure Javascript. Nilac is currently
|
2
|
+
#written in Ruby but will be self hosted in the upcoming years.
|
3
|
+
|
4
|
+
#Nila and Nilac are being crafted by Adhithya Rajasekaran and Sri Madhavi Rajasekaran
|
5
|
+
|
6
|
+
require 'slop'
|
7
|
+
require 'fileutils'
|
8
|
+
|
9
|
+
def compile(input_file_path,*output_file_name)
|
10
|
+
|
11
|
+
def read_file_line_by_line(input_path)
|
12
|
+
|
13
|
+
file_id = open(input_path)
|
14
|
+
|
15
|
+
file_line_by_line = file_id.readlines()
|
16
|
+
|
17
|
+
file_id.close
|
18
|
+
|
19
|
+
return file_line_by_line
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
def extract_parsable_file(input_file_contents)
|
24
|
+
|
25
|
+
reversed_file_contents = input_file_contents.reverse
|
26
|
+
|
27
|
+
line_counter = 0
|
28
|
+
|
29
|
+
if input_file_contents.join.include?("__END__")
|
30
|
+
|
31
|
+
while !reversed_file_contents[line_counter].strip.include?("__END__")
|
32
|
+
|
33
|
+
line_counter += 1
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
return_contents = input_file_contents[0...-1*line_counter-1]
|
38
|
+
|
39
|
+
else
|
40
|
+
|
41
|
+
input_file_contents
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
def replace_multiline_comments(input_file_contents,nila_file_path,*output_js_file_path)
|
48
|
+
|
49
|
+
#This method will replace both the single and multiline comments
|
50
|
+
#
|
51
|
+
#Single line comment will be replaced by => --single_line_comment[n]
|
52
|
+
#
|
53
|
+
#Multiline comment will be replaced by => --multiline_comment[n]
|
54
|
+
|
55
|
+
def find_all_matching_indices(input_string,pattern)
|
56
|
+
|
57
|
+
locations = []
|
58
|
+
|
59
|
+
index = input_string.index(pattern)
|
60
|
+
|
61
|
+
while index != nil
|
62
|
+
|
63
|
+
locations << index
|
64
|
+
|
65
|
+
index = input_string.index(pattern,index+1)
|
66
|
+
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
return locations
|
71
|
+
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
def find_file_path(input_path,file_extension)
|
76
|
+
|
77
|
+
extension_remover = input_path.split(file_extension)
|
78
|
+
|
79
|
+
remaining_string = extension_remover[0].reverse
|
80
|
+
|
81
|
+
path_finder = remaining_string.index("/")
|
82
|
+
|
83
|
+
remaining_string = remaining_string.reverse
|
84
|
+
|
85
|
+
return remaining_string[0...remaining_string.length-path_finder]
|
86
|
+
|
87
|
+
end
|
88
|
+
|
89
|
+
def find_file_name(input_path,file_extension)
|
90
|
+
|
91
|
+
extension_remover = input_path.split(file_extension)
|
92
|
+
|
93
|
+
remaining_string = extension_remover[0].reverse
|
94
|
+
|
95
|
+
path_finder = remaining_string.index("/")
|
96
|
+
|
97
|
+
remaining_string = remaining_string.reverse
|
98
|
+
|
99
|
+
return remaining_string[remaining_string.length-path_finder..-1]
|
100
|
+
|
101
|
+
end
|
102
|
+
|
103
|
+
multiline_comments = []
|
104
|
+
|
105
|
+
file_contents_as_string = input_file_contents.join
|
106
|
+
|
107
|
+
modified_file_contents = file_contents_as_string.dup
|
108
|
+
|
109
|
+
multiline_comment_counter = 1
|
110
|
+
|
111
|
+
multiline_comments_start = find_all_matching_indices(file_contents_as_string,"=begin")
|
112
|
+
|
113
|
+
multiline_comments_end = find_all_matching_indices(file_contents_as_string,"=end")
|
114
|
+
|
115
|
+
for y in 0...multiline_comments_start.length
|
116
|
+
|
117
|
+
start_of_multiline_comment = multiline_comments_start[y]
|
118
|
+
|
119
|
+
end_of_multiline_comment = multiline_comments_end[y]
|
120
|
+
|
121
|
+
multiline_comment = file_contents_as_string[start_of_multiline_comment..end_of_multiline_comment+3]
|
122
|
+
|
123
|
+
modified_file_contents = modified_file_contents.gsub(multiline_comment,"--multiline_comment[#{multiline_comment_counter}]")
|
124
|
+
|
125
|
+
multiline_comment_counter += 1
|
126
|
+
|
127
|
+
multiline_comments << multiline_comment
|
128
|
+
|
129
|
+
|
130
|
+
end
|
131
|
+
|
132
|
+
temporary_nila_file = find_file_path(nila_file_path,".nila") + "temp_nila.nila"
|
133
|
+
|
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
|
143
|
+
|
144
|
+
file_id = open(temporary_nila_file, 'w')
|
145
|
+
|
146
|
+
file_id2 = open(output_js_file, 'w')
|
147
|
+
|
148
|
+
file_id.write(modified_file_contents)
|
149
|
+
|
150
|
+
file_id.close()
|
151
|
+
|
152
|
+
file_id2.close()
|
153
|
+
|
154
|
+
line_by_line_contents = read_file_line_by_line(temporary_nila_file)
|
155
|
+
|
156
|
+
comments = multiline_comments.dup
|
157
|
+
|
158
|
+
return line_by_line_contents,comments,temporary_nila_file,output_js_file
|
159
|
+
|
160
|
+
end
|
161
|
+
|
162
|
+
def split_semicolon_seperated_expressions(input_file_contents)
|
163
|
+
|
164
|
+
modified_file_contents = input_file_contents.dup
|
165
|
+
|
166
|
+
input_file_contents.each_with_index do |line,index|
|
167
|
+
|
168
|
+
if line.include?("\"")
|
169
|
+
|
170
|
+
first_index = line.index("\"")
|
171
|
+
|
172
|
+
modified_line = line.sub(line[first_index..line.index("\"",first_index+1)],"--string")
|
173
|
+
|
174
|
+
elsif line.include?("'")
|
175
|
+
|
176
|
+
first_index = line.index("'")
|
177
|
+
|
178
|
+
modified_line = line.sub(line[first_index..line.index("'",first_index+1)],"--string")
|
179
|
+
|
180
|
+
else
|
181
|
+
|
182
|
+
modified_line = line
|
183
|
+
|
184
|
+
end
|
185
|
+
|
186
|
+
if modified_line.include?(";")
|
187
|
+
|
188
|
+
replacement_line = modified_file_contents[index]
|
189
|
+
|
190
|
+
replacement_line = replacement_line.split(";").join("\n\n") + "\n"
|
191
|
+
|
192
|
+
modified_file_contents[index] = replacement_line
|
193
|
+
|
194
|
+
end
|
195
|
+
|
196
|
+
end
|
197
|
+
|
198
|
+
return modified_file_contents
|
199
|
+
|
200
|
+
end
|
201
|
+
|
202
|
+
def compile_interpolated_strings(input_file_contents)
|
203
|
+
|
204
|
+
modified_file_contents = input_file_contents.dup
|
205
|
+
|
206
|
+
input_file_contents.each_with_index do |line,index|
|
207
|
+
|
208
|
+
if line.include?("\#{")
|
209
|
+
|
210
|
+
interpolated_strings = line.scan(/\#{\S{1,}}/)
|
211
|
+
|
212
|
+
interpolated_strings.each do |interpol|
|
213
|
+
|
214
|
+
string_split = line.split(interpol)
|
215
|
+
|
216
|
+
if string_split[1].eql?("\"\n")
|
217
|
+
|
218
|
+
replacement_string = "\" + " + interpol[2...-1]
|
219
|
+
|
220
|
+
modified_file_contents[index] = modified_file_contents[index].sub(interpol+"\"",replacement_string)
|
221
|
+
|
222
|
+
elsif string_split[1].eql?("\")\n")
|
223
|
+
|
224
|
+
replacement_string = "\" + " + interpol[2...-1]
|
225
|
+
|
226
|
+
modified_file_contents[index] = modified_file_contents[index].sub(interpol+"\"",replacement_string)
|
227
|
+
|
228
|
+
else
|
229
|
+
|
230
|
+
replacement_string = "\" + " + interpol[2...-1] + " + \""
|
231
|
+
|
232
|
+
modified_file_contents[index] = modified_file_contents[index].sub(interpol,replacement_string)
|
233
|
+
|
234
|
+
end
|
235
|
+
|
236
|
+
end
|
237
|
+
|
238
|
+
end
|
239
|
+
|
240
|
+
end
|
241
|
+
|
242
|
+
return modified_file_contents
|
243
|
+
|
244
|
+
end
|
245
|
+
|
246
|
+
def replace_singleline_comments(input_file_contents)
|
247
|
+
|
248
|
+
single_line_comments = []
|
249
|
+
|
250
|
+
singleline_comment_counter = 1
|
251
|
+
|
252
|
+
for x in 0...input_file_contents.length
|
253
|
+
|
254
|
+
current_row = input_file_contents[x]
|
255
|
+
|
256
|
+
if current_row.include?("#")
|
257
|
+
|
258
|
+
comment_start = current_row.index("#")
|
259
|
+
|
260
|
+
if current_row[comment_start+1] != "{"
|
261
|
+
|
262
|
+
comment = current_row[comment_start..-1]
|
263
|
+
|
264
|
+
single_line_comments << comment
|
265
|
+
|
266
|
+
current_row = current_row.gsub(comment,"--single_line_comment[#{singleline_comment_counter}]")
|
267
|
+
|
268
|
+
singleline_comment_counter += 1
|
269
|
+
|
270
|
+
end
|
271
|
+
|
272
|
+
end
|
273
|
+
|
274
|
+
input_file_contents[x] = current_row
|
275
|
+
|
276
|
+
end
|
277
|
+
|
278
|
+
return input_file_contents,single_line_comments
|
279
|
+
|
280
|
+
end
|
281
|
+
|
282
|
+
def replace_named_functions(nila_file_contents,temporary_nila_file)
|
283
|
+
|
284
|
+
def extract_array(input_array,start_index,end_index)
|
285
|
+
|
286
|
+
return input_array[start_index..end_index]
|
287
|
+
|
288
|
+
end
|
289
|
+
|
290
|
+
end_locations = []
|
291
|
+
|
292
|
+
key_word_locations = []
|
293
|
+
|
294
|
+
start_blocks = []
|
295
|
+
|
296
|
+
end_blocks = []
|
297
|
+
|
298
|
+
nila_regexp = /(def )/
|
299
|
+
|
300
|
+
named_code_blocks = []
|
301
|
+
|
302
|
+
for x in 0...nila_file_contents.length
|
303
|
+
|
304
|
+
current_row = nila_file_contents[x]
|
305
|
+
|
306
|
+
if current_row.index(nila_regexp) != nil
|
307
|
+
|
308
|
+
key_word_locations << x
|
309
|
+
|
310
|
+
elsif current_row.include?("end\n") || current_row.include?("end")
|
311
|
+
|
312
|
+
end_locations << x
|
313
|
+
|
314
|
+
|
315
|
+
end
|
316
|
+
|
317
|
+
|
318
|
+
end
|
319
|
+
|
320
|
+
modified_file_contents = nila_file_contents.dup
|
321
|
+
|
322
|
+
for y in 0...end_locations.length
|
323
|
+
|
324
|
+
current_location = end_locations[y]
|
325
|
+
|
326
|
+
current_string = modified_file_contents[current_location]
|
327
|
+
|
328
|
+
finder_location = current_location
|
329
|
+
|
330
|
+
while current_string.index(nila_regexp) == nil
|
331
|
+
|
332
|
+
finder_location -= 1
|
333
|
+
|
334
|
+
current_string = modified_file_contents[finder_location]
|
335
|
+
|
336
|
+
end
|
337
|
+
|
338
|
+
code_block_begin = finder_location
|
339
|
+
|
340
|
+
code_block_end = current_location
|
341
|
+
|
342
|
+
start_blocks << code_block_begin
|
343
|
+
|
344
|
+
end_blocks << code_block_end
|
345
|
+
|
346
|
+
code_block_begin_string_split = modified_file_contents[code_block_begin].split(" ")
|
347
|
+
|
348
|
+
code_block_begin_string_split[0] = code_block_begin_string_split[0].reverse
|
349
|
+
|
350
|
+
code_block_begin_string = code_block_begin_string_split.join(" ")
|
351
|
+
|
352
|
+
modified_file_contents[code_block_begin] = code_block_begin_string
|
353
|
+
|
354
|
+
end
|
355
|
+
|
356
|
+
final_modified_file_contents = nila_file_contents.dup
|
357
|
+
|
358
|
+
joined_file_contents = final_modified_file_contents.join
|
359
|
+
|
360
|
+
while start_blocks.length != 0
|
361
|
+
|
362
|
+
top_most_level = start_blocks.min
|
363
|
+
|
364
|
+
top_most_level_index = start_blocks.index(top_most_level)
|
365
|
+
|
366
|
+
matching_level = end_blocks[top_most_level_index]
|
367
|
+
|
368
|
+
named_code_blocks << extract_array(final_modified_file_contents,top_most_level,matching_level)
|
369
|
+
|
370
|
+
start_blocks.delete_at(top_most_level_index)
|
371
|
+
|
372
|
+
end_blocks.delete(matching_level)
|
373
|
+
|
374
|
+
end
|
375
|
+
|
376
|
+
codeblock_counter = 1
|
377
|
+
|
378
|
+
named_functions = named_code_blocks.dup
|
379
|
+
|
380
|
+
nested_functions = []
|
381
|
+
|
382
|
+
named_code_blocks.each do |codeblock|
|
383
|
+
|
384
|
+
if joined_file_contents.include?(codeblock.join)
|
385
|
+
|
386
|
+
joined_file_contents = joined_file_contents.sub(codeblock.join,"--named_function[#{codeblock_counter}]\n")
|
387
|
+
|
388
|
+
codeblock_counter += 1
|
389
|
+
|
390
|
+
nested_functions = nested_functions + [[]]
|
391
|
+
|
392
|
+
else
|
393
|
+
|
394
|
+
nested_functions[codeblock_counter-2] << codeblock
|
395
|
+
|
396
|
+
named_functions.delete(codeblock)
|
397
|
+
|
398
|
+
end
|
399
|
+
|
400
|
+
end
|
401
|
+
|
402
|
+
file_id = open(temporary_nila_file, 'w')
|
403
|
+
|
404
|
+
file_id.write(joined_file_contents)
|
405
|
+
|
406
|
+
file_id.close()
|
407
|
+
|
408
|
+
line_by_line_contents = read_file_line_by_line(temporary_nila_file)
|
409
|
+
|
410
|
+
return line_by_line_contents,named_functions,nested_functions
|
411
|
+
|
412
|
+
|
413
|
+
end
|
414
|
+
|
415
|
+
def get_variables(input_file_contents,temporary_nila_file)
|
416
|
+
|
417
|
+
#This method is solely focused on getting a list of variables to be declared.
|
418
|
+
#Since Javascript is a dynamic language, Nila doesn't have to worry about following up on those variables.
|
419
|
+
|
420
|
+
#Semicolons are required in Javascript for successful compilation. So this method adds semicolons at the end of each
|
421
|
+
#variable usage statements.
|
422
|
+
|
423
|
+
variables = []
|
424
|
+
|
425
|
+
for x in 0...input_file_contents.length
|
426
|
+
|
427
|
+
current_row = input_file_contents[x]
|
428
|
+
|
429
|
+
#The condition below verifies if the rows contain any equation operators.
|
430
|
+
|
431
|
+
if current_row.include?("=") and !current_row.include?("def")
|
432
|
+
|
433
|
+
current_row = current_row.rstrip + "\n"
|
434
|
+
|
435
|
+
current_row_split = current_row.split("=")
|
436
|
+
|
437
|
+
for y in 0...current_row_split.length
|
438
|
+
|
439
|
+
current_row_split[y] = current_row_split[y].strip
|
440
|
+
|
441
|
+
|
442
|
+
end
|
443
|
+
|
444
|
+
variables << current_row_split[0]
|
445
|
+
|
446
|
+
|
447
|
+
end
|
448
|
+
|
449
|
+
input_file_contents[x] = current_row
|
450
|
+
|
451
|
+
end
|
452
|
+
|
453
|
+
file_contents_as_string = input_file_contents.join
|
454
|
+
|
455
|
+
file_id = open(temporary_nila_file, 'w')
|
456
|
+
|
457
|
+
file_id.write(file_contents_as_string)
|
458
|
+
|
459
|
+
file_id.close()
|
460
|
+
|
461
|
+
line_by_line_contents = read_file_line_by_line(temporary_nila_file)
|
462
|
+
|
463
|
+
if variables.length > 0
|
464
|
+
|
465
|
+
variable_declaration_string = "var " + variables.uniq.join(", ") + "\n\n"
|
466
|
+
|
467
|
+
line_by_line_contents = [variable_declaration_string,line_by_line_contents].flatten
|
468
|
+
|
469
|
+
end
|
470
|
+
|
471
|
+
return variables.uniq,line_by_line_contents
|
472
|
+
|
473
|
+
end
|
474
|
+
|
475
|
+
def remove_question_marks(input_file_contents,variable_list,temporary_nila_file)
|
476
|
+
|
477
|
+
#A method to remove question marks from global variable names. Local variables are dealt
|
478
|
+
#with in their appropriate scope.
|
479
|
+
|
480
|
+
#Params:
|
481
|
+
#input_file_contents => An array containing the contents of the input nila file
|
482
|
+
#variable_list => An array containing all the global variables declared in the file
|
483
|
+
#temporary_nila_file => A file object used to write temporary contents
|
484
|
+
|
485
|
+
#Example:
|
486
|
+
|
487
|
+
#Nila
|
488
|
+
#isprime? = false
|
489
|
+
|
490
|
+
#Javascript Output
|
491
|
+
#var isprime;
|
492
|
+
#isprime = false;
|
493
|
+
|
494
|
+
#Returns a modified input_file_contents with all the question marks removed
|
495
|
+
|
496
|
+
joined_file_contents = input_file_contents.join
|
497
|
+
|
498
|
+
variable_list.each do |var|
|
499
|
+
|
500
|
+
if var.include? "?"
|
501
|
+
|
502
|
+
joined_file_contents = joined_file_contents.gsub(var,var[0...-1])
|
503
|
+
|
504
|
+
end
|
505
|
+
|
506
|
+
end
|
507
|
+
|
508
|
+
file_id = open(temporary_nila_file, 'w')
|
509
|
+
|
510
|
+
file_id.write(joined_file_contents)
|
511
|
+
|
512
|
+
file_id.close()
|
513
|
+
|
514
|
+
line_by_line_contents = read_file_line_by_line(temporary_nila_file)
|
515
|
+
|
516
|
+
return line_by_line_contents
|
517
|
+
|
518
|
+
end
|
519
|
+
|
520
|
+
def compile_arrays(input_file_contents)
|
521
|
+
|
522
|
+
#Currently the following kinds of array constructs are compilable
|
523
|
+
|
524
|
+
# 1. %w{} syntax
|
525
|
+
# 2. Range - Coming soon!
|
526
|
+
|
527
|
+
def extract(input_string,pattern_start,pattern_end)
|
528
|
+
|
529
|
+
def find_all_matching_indices(input_string,pattern)
|
530
|
+
|
531
|
+
locations = []
|
532
|
+
|
533
|
+
index = input_string.index(pattern)
|
534
|
+
|
535
|
+
while index != nil
|
536
|
+
|
537
|
+
locations << index
|
538
|
+
|
539
|
+
index = input_string.index(pattern,index+1)
|
540
|
+
|
541
|
+
|
542
|
+
end
|
543
|
+
|
544
|
+
return locations
|
545
|
+
|
546
|
+
|
547
|
+
end
|
548
|
+
|
549
|
+
all_start_locations = find_all_matching_indices(input_string,pattern_start)
|
550
|
+
|
551
|
+
all_end_locations = find_all_matching_indices(input_string,pattern_end)
|
552
|
+
|
553
|
+
pattern = []
|
554
|
+
|
555
|
+
all_start_locations.each_with_index do |location,index|
|
556
|
+
|
557
|
+
pattern << input_string[location..all_end_locations[index]]
|
558
|
+
|
559
|
+
end
|
560
|
+
|
561
|
+
return pattern
|
562
|
+
|
563
|
+
end
|
564
|
+
|
565
|
+
def compile_w_syntax(input_string)
|
566
|
+
|
567
|
+
modified_input_string = input_string[3...-1]
|
568
|
+
|
569
|
+
string_split = modified_input_string.split(" ")
|
570
|
+
|
571
|
+
return string_split.to_s
|
572
|
+
|
573
|
+
end
|
574
|
+
|
575
|
+
modified_file_contents = input_file_contents.dup
|
576
|
+
|
577
|
+
input_file_contents.each_with_index do |line,index|
|
578
|
+
|
579
|
+
if line.include?("%w{")
|
580
|
+
|
581
|
+
string_arrays = extract(line,"%w{","}")
|
582
|
+
|
583
|
+
string_arrays.each do |array|
|
584
|
+
|
585
|
+
modified_file_contents[index] = modified_file_contents[index].sub(array,compile_w_syntax(array))
|
586
|
+
|
587
|
+
end
|
588
|
+
|
589
|
+
end
|
590
|
+
|
591
|
+
end
|
592
|
+
|
593
|
+
return modified_file_contents
|
594
|
+
|
595
|
+
end
|
596
|
+
|
597
|
+
def compile_named_functions(input_file_contents,named_code_blocks,nested_functions,temporary_nila_file)
|
598
|
+
|
599
|
+
#This method compiles all the named Nila functions. Below is an example of what is meant
|
600
|
+
#by named/explicit function
|
601
|
+
|
602
|
+
#def square(input_number)
|
603
|
+
#
|
604
|
+
# input_number*input_number
|
605
|
+
#
|
606
|
+
#end
|
607
|
+
|
608
|
+
#The above function will compile to
|
609
|
+
|
610
|
+
#function square(input_number) {
|
611
|
+
#
|
612
|
+
# return input_number*input_number;
|
613
|
+
#
|
614
|
+
# }
|
615
|
+
|
616
|
+
def is_parameterless?(input_function_block)
|
617
|
+
|
618
|
+
if input_function_block[0].include?("(")
|
619
|
+
|
620
|
+
false
|
621
|
+
|
622
|
+
else
|
623
|
+
|
624
|
+
true
|
625
|
+
|
626
|
+
end
|
627
|
+
|
628
|
+
end
|
629
|
+
|
630
|
+
def lexical_scoped_variables(input_function_block)
|
631
|
+
|
632
|
+
#This method will pickup and declare all the variables inside a function block. In future, this method will be
|
633
|
+
#merged with the get variables method
|
634
|
+
|
635
|
+
variables = []
|
636
|
+
|
637
|
+
input_function_block.each do |line|
|
638
|
+
|
639
|
+
if line.include? "=" and !line.include?("def")
|
640
|
+
|
641
|
+
current_line_split = line.strip.split("=")
|
642
|
+
|
643
|
+
variables << current_line_split[0].rstrip
|
644
|
+
|
645
|
+
end
|
646
|
+
|
647
|
+
end
|
648
|
+
|
649
|
+
variables.uniq
|
650
|
+
|
651
|
+
end
|
652
|
+
|
653
|
+
def remove_question_marks(input_file_contents,input_list,temporary_nila_file)
|
654
|
+
|
655
|
+
joined_file_contents = input_file_contents.join
|
656
|
+
|
657
|
+
input_list.each do |element|
|
658
|
+
|
659
|
+
if element.include? "?"
|
660
|
+
|
661
|
+
joined_file_contents = joined_file_contents.gsub(element,element[0...-1])
|
662
|
+
|
663
|
+
end
|
664
|
+
|
665
|
+
end
|
666
|
+
|
667
|
+
file_id = open(temporary_nila_file, 'w')
|
668
|
+
|
669
|
+
file_id.write(joined_file_contents)
|
670
|
+
|
671
|
+
file_id.close()
|
672
|
+
|
673
|
+
line_by_line_contents = read_file_line_by_line(temporary_nila_file)
|
674
|
+
|
675
|
+
return line_by_line_contents
|
676
|
+
|
677
|
+
end
|
678
|
+
|
679
|
+
def add_auto_return_statement(input_array)
|
680
|
+
|
681
|
+
joined_array = input_array.join
|
682
|
+
|
683
|
+
reversed_input_array = input_array.reverse
|
684
|
+
|
685
|
+
if !joined_array.include?("return ")
|
686
|
+
|
687
|
+
rejected_array = reversed_input_array.reject {|content| content.lstrip.eql?("")}
|
688
|
+
|
689
|
+
rejected_array = rejected_array.reject {|content| content.strip.eql? "}"}
|
690
|
+
|
691
|
+
last_statement = rejected_array[0]
|
692
|
+
|
693
|
+
replacement_string = "return #{last_statement.lstrip}"
|
694
|
+
|
695
|
+
input_array[input_array.index(last_statement)] = replacement_string
|
696
|
+
|
697
|
+
end
|
698
|
+
|
699
|
+
return input_array
|
700
|
+
|
701
|
+
end
|
702
|
+
|
703
|
+
def compile_function(input_array,temporary_nila_file)
|
704
|
+
|
705
|
+
modified_input_array = input_array.dup
|
706
|
+
|
707
|
+
if is_parameterless?(modified_input_array)
|
708
|
+
|
709
|
+
if modified_input_array[0].include?("--single")
|
710
|
+
|
711
|
+
modified_input_array[0] = input_array[0].sub "def","function"
|
712
|
+
|
713
|
+
interim_string = modified_input_array[0].split("--single")
|
714
|
+
|
715
|
+
modified_input_array[0] = interim_string[0].rstrip + "() {\n--single" + interim_string[1]
|
716
|
+
|
717
|
+
|
718
|
+
elsif modified_input_array[0].include?("--multi")
|
719
|
+
|
720
|
+
modified_input_array[0] = input_array[0].sub "def","function"
|
721
|
+
|
722
|
+
interim_string = modified_input_array[0].split("--multi")
|
723
|
+
|
724
|
+
modified_input_array[0] = interim_string[0].rstrip + "() {\n--multi" + interim_string[1]
|
725
|
+
|
726
|
+
else
|
727
|
+
|
728
|
+
modified_input_array[0] = input_array[0].sub "def","function"
|
729
|
+
|
730
|
+
modified_input_array[0] = modified_input_array[0].rstrip + "() {\n"
|
731
|
+
|
732
|
+
end
|
733
|
+
|
734
|
+
else
|
735
|
+
|
736
|
+
if modified_input_array[0].include?("--single")
|
737
|
+
|
738
|
+
modified_input_array[0] = input_array[0].sub "def","function"
|
739
|
+
|
740
|
+
interim_string = modified_input_array[0].split("--single")
|
741
|
+
|
742
|
+
modified_input_array[0] = interim_string[0].rstrip + " {\n--single" + interim_string[1]
|
743
|
+
|
744
|
+
|
745
|
+
elsif modified_input_array[0].include?("--multi")
|
746
|
+
|
747
|
+
modified_input_array[0] = input_array[0].sub "def","function"
|
748
|
+
|
749
|
+
interim_string = modified_input_array[0].split("--multi")
|
750
|
+
|
751
|
+
modified_input_array[0] = interim_string[0].rstrip + " {\n--multi" + interim_string[1]
|
752
|
+
|
753
|
+
else
|
754
|
+
|
755
|
+
modified_input_array[0] = input_array[0].sub "def","function"
|
756
|
+
|
757
|
+
modified_input_array[0] = modified_input_array[0].rstrip + " {\n"
|
758
|
+
|
759
|
+
end
|
760
|
+
|
761
|
+
end
|
762
|
+
|
763
|
+
modified_input_array[-1] = input_array[-1].sub "end","}\n"
|
764
|
+
|
765
|
+
variables = lexical_scoped_variables(modified_input_array)
|
766
|
+
|
767
|
+
if !variables.empty?
|
768
|
+
|
769
|
+
variable_string = "\nvar " + variables.join(", ") + "\n"
|
770
|
+
|
771
|
+
modified_input_array.insert(1,variable_string)
|
772
|
+
|
773
|
+
end
|
774
|
+
|
775
|
+
modified_input_array = remove_question_marks(modified_input_array,variables,temporary_nila_file)
|
776
|
+
|
777
|
+
modified_input_array = add_auto_return_statement(modified_input_array)
|
778
|
+
|
779
|
+
return modified_input_array
|
780
|
+
|
781
|
+
end
|
782
|
+
|
783
|
+
def extract_function_name(input_code_block)
|
784
|
+
|
785
|
+
first_line = input_code_block[0]
|
786
|
+
|
787
|
+
first_line_split = first_line.split(" ")
|
788
|
+
|
789
|
+
if first_line_split[1].include?("(")
|
790
|
+
|
791
|
+
function_name,parameters = first_line_split[1].split("(")
|
792
|
+
|
793
|
+
else
|
794
|
+
|
795
|
+
function_name = first_line_split[1]
|
796
|
+
|
797
|
+
end
|
798
|
+
|
799
|
+
return function_name
|
800
|
+
|
801
|
+
end
|
802
|
+
|
803
|
+
joined_file_contents = input_file_contents.join
|
804
|
+
|
805
|
+
codeblock_counter = 1
|
806
|
+
|
807
|
+
function_names = []
|
808
|
+
|
809
|
+
named_code_blocks.each do |codeblock|
|
810
|
+
|
811
|
+
function_names[codeblock_counter-1] = []
|
812
|
+
|
813
|
+
joined_file_contents = joined_file_contents.sub("--named_function[#{codeblock_counter}]\n",compile_function(codeblock,temporary_nila_file).join)
|
814
|
+
|
815
|
+
codeblock_counter += 1
|
816
|
+
|
817
|
+
current_nested_functions = nested_functions[codeblock_counter-2]
|
818
|
+
|
819
|
+
function_names[codeblock_counter-2] << extract_function_name(codeblock)
|
820
|
+
|
821
|
+
current_nested_functions.each do |nested_function|
|
822
|
+
|
823
|
+
function_names[codeblock_counter-2] << extract_function_name(nested_function)
|
824
|
+
|
825
|
+
joined_file_contents = joined_file_contents.sub(nested_function.join,compile_function(nested_function,temporary_nila_file).join)
|
826
|
+
|
827
|
+
end
|
828
|
+
|
829
|
+
end
|
830
|
+
|
831
|
+
file_id = open(temporary_nila_file, 'w')
|
832
|
+
|
833
|
+
file_id.write(joined_file_contents)
|
834
|
+
|
835
|
+
file_id.close()
|
836
|
+
|
837
|
+
line_by_line_contents = read_file_line_by_line(temporary_nila_file)
|
838
|
+
|
839
|
+
return line_by_line_contents,function_names
|
840
|
+
|
841
|
+
end
|
842
|
+
|
843
|
+
def compile_custom_function_map(input_file_contents)
|
844
|
+
|
845
|
+
function_map_replacements = {
|
846
|
+
|
847
|
+
"puts" => "console.log",
|
848
|
+
|
849
|
+
"print" => "console.log"
|
850
|
+
|
851
|
+
}
|
852
|
+
|
853
|
+
function_map = function_map_replacements.keys
|
854
|
+
|
855
|
+
modified_file_contents = input_file_contents.dup
|
856
|
+
|
857
|
+
input_file_contents.each_with_index do |line,index|
|
858
|
+
|
859
|
+
function_map.each do |function|
|
860
|
+
|
861
|
+
if line.include?(function+"(") or line.include?(function+" ")
|
862
|
+
|
863
|
+
modified_file_contents[index] = line.sub(function,function_map_replacements[function])
|
864
|
+
|
865
|
+
end
|
866
|
+
|
867
|
+
end
|
868
|
+
|
869
|
+
end
|
870
|
+
|
871
|
+
return modified_file_contents,function_map_replacements.values
|
872
|
+
|
873
|
+
end
|
874
|
+
|
875
|
+
def compile_whitespace_delimited_functions(input_file_contents,function_names,temporary_nila_file)
|
876
|
+
|
877
|
+
def extract(input_string,pattern_start,pattern_end)
|
878
|
+
|
879
|
+
def find_all_matching_indices(input_string,pattern)
|
880
|
+
|
881
|
+
locations = []
|
882
|
+
|
883
|
+
index = input_string.index(pattern)
|
884
|
+
|
885
|
+
while index != nil
|
886
|
+
|
887
|
+
locations << index
|
888
|
+
|
889
|
+
index = input_string.index(pattern,index+1)
|
890
|
+
|
891
|
+
|
892
|
+
end
|
893
|
+
|
894
|
+
return locations
|
895
|
+
|
896
|
+
|
897
|
+
end
|
898
|
+
|
899
|
+
all_start_locations = find_all_matching_indices(input_string,pattern_start)
|
900
|
+
|
901
|
+
pattern = []
|
902
|
+
|
903
|
+
all_start_locations.each do |location|
|
904
|
+
|
905
|
+
extracted_string = input_string[location..-1]
|
906
|
+
|
907
|
+
pattern << extracted_string[0..extracted_string.index(pattern_end)]
|
908
|
+
|
909
|
+
end
|
910
|
+
|
911
|
+
return pattern
|
912
|
+
|
913
|
+
end
|
914
|
+
|
915
|
+
input_file_contents[-1] = input_file_contents[-1] + "\n" if !input_file_contents[-1].include?("\n")
|
916
|
+
|
917
|
+
joined_file_contents = input_file_contents.join
|
918
|
+
|
919
|
+
function_names.each do |list_of_functions|
|
920
|
+
|
921
|
+
list_of_functions.each do |function|
|
922
|
+
|
923
|
+
matching_strings = extract(joined_file_contents,function+" ","\n")
|
924
|
+
|
925
|
+
matching_strings.each do |string|
|
926
|
+
|
927
|
+
modified_string = string.dup
|
928
|
+
|
929
|
+
modified_string = modified_string.sub(function+" ",function+"(")
|
930
|
+
|
931
|
+
modified_string = modified_string.sub("\n",")\n")
|
932
|
+
|
933
|
+
joined_file_contents = joined_file_contents.sub(string,modified_string)
|
934
|
+
|
935
|
+
end
|
936
|
+
|
937
|
+
end
|
938
|
+
|
939
|
+
end
|
940
|
+
|
941
|
+
file_id = open(temporary_nila_file, 'w')
|
942
|
+
|
943
|
+
file_id.write(joined_file_contents)
|
944
|
+
|
945
|
+
file_id.close()
|
946
|
+
|
947
|
+
line_by_line_contents = read_file_line_by_line(temporary_nila_file)
|
948
|
+
|
949
|
+
return line_by_line_contents
|
950
|
+
|
951
|
+
end
|
952
|
+
|
953
|
+
def compile_conditional_structures(input_file_contents,temporary_nila_file)
|
954
|
+
|
955
|
+
#Currently the following conditional structures have been implemented
|
956
|
+
|
957
|
+
#1. If and While Inline Statements
|
958
|
+
|
959
|
+
def compile_inline_conditionals(input_file_contents,temporary_nila_file)
|
960
|
+
|
961
|
+
conditionals = [/( if )/,/( while )/]
|
962
|
+
|
963
|
+
plain_conditionals = [" if "," while "]
|
964
|
+
|
965
|
+
joined_file_contents = input_file_contents.join
|
966
|
+
|
967
|
+
output_statement = ""
|
968
|
+
|
969
|
+
conditionals.each_with_index do |regex,index|
|
970
|
+
|
971
|
+
matching_lines = input_file_contents.reject {|content| !content.index(regex)}
|
972
|
+
|
973
|
+
matching_lines.each do |line|
|
974
|
+
|
975
|
+
line_split = line.split(plain_conditionals[index])
|
976
|
+
|
977
|
+
if index == 0
|
978
|
+
|
979
|
+
output_statement = "if (#{line_split[1].lstrip.rstrip}) {\n\n#{line_split[0]}\n}\n"
|
980
|
+
|
981
|
+
elsif index == 1
|
982
|
+
|
983
|
+
output_statement = "while (#{line_split[1].lstrip.rstrip}) {\n\n#{line_split[0]}\n}\n"
|
984
|
+
|
985
|
+
end
|
986
|
+
|
987
|
+
joined_file_contents = joined_file_contents.sub(line,output_statement)
|
988
|
+
|
989
|
+
end
|
990
|
+
|
991
|
+
end
|
992
|
+
|
993
|
+
file_id = open(temporary_nila_file, 'w')
|
994
|
+
|
995
|
+
file_id.write(joined_file_contents)
|
996
|
+
|
997
|
+
file_id.close()
|
998
|
+
|
999
|
+
line_by_line_contents = read_file_line_by_line(temporary_nila_file)
|
1000
|
+
|
1001
|
+
return line_by_line_contents
|
1002
|
+
|
1003
|
+
end
|
1004
|
+
|
1005
|
+
line_by_line_contents = compile_inline_conditionals(input_file_contents,temporary_nila_file)
|
1006
|
+
|
1007
|
+
end
|
1008
|
+
|
1009
|
+
def compile_comments(input_file_contents,comments,temporary_nila_file)
|
1010
|
+
|
1011
|
+
#This method converts Nila comments into pure Javascript comments. This method
|
1012
|
+
#handles both single line and multiline comments.
|
1013
|
+
|
1014
|
+
file_contents_as_string = input_file_contents.join
|
1015
|
+
|
1016
|
+
single_line_comments = comments[0]
|
1017
|
+
|
1018
|
+
multiline_comments = comments[1]
|
1019
|
+
|
1020
|
+
single_line_comment_counter = 1
|
1021
|
+
|
1022
|
+
multi_line_comment_counter = 1
|
1023
|
+
|
1024
|
+
for x in 0...single_line_comments.length
|
1025
|
+
|
1026
|
+
current_singleline_comment = "--single_line_comment[#{single_line_comment_counter}]"
|
1027
|
+
|
1028
|
+
replacement_singleline_string = single_line_comments[x].sub("#","//")
|
1029
|
+
|
1030
|
+
file_contents_as_string = file_contents_as_string.sub(current_singleline_comment,replacement_singleline_string)
|
1031
|
+
|
1032
|
+
single_line_comment_counter += 1
|
1033
|
+
|
1034
|
+
|
1035
|
+
end
|
1036
|
+
|
1037
|
+
for y in 0...multiline_comments.length
|
1038
|
+
|
1039
|
+
current_multiline_comment = "--multiline_comment[#{multi_line_comment_counter}]"
|
1040
|
+
|
1041
|
+
replacement_multiline_string = multiline_comments[y].sub("=begin","/*\n")
|
1042
|
+
|
1043
|
+
replacement_multiline_string = replacement_multiline_string.sub("=end","\n*/")
|
1044
|
+
|
1045
|
+
file_contents_as_string = file_contents_as_string.sub(current_multiline_comment,replacement_multiline_string)
|
1046
|
+
|
1047
|
+
multi_line_comment_counter += 1
|
1048
|
+
|
1049
|
+
end
|
1050
|
+
|
1051
|
+
file_id = open(temporary_nila_file, 'w')
|
1052
|
+
|
1053
|
+
file_id.write(file_contents_as_string)
|
1054
|
+
|
1055
|
+
file_id.close()
|
1056
|
+
|
1057
|
+
line_by_line_contents = read_file_line_by_line(temporary_nila_file)
|
1058
|
+
|
1059
|
+
line_by_line_contents
|
1060
|
+
|
1061
|
+
end
|
1062
|
+
|
1063
|
+
def add_semicolons(input_file_contents)
|
1064
|
+
|
1065
|
+
def comment(input_string)
|
1066
|
+
|
1067
|
+
if input_string.include?("--single_line_comment")
|
1068
|
+
|
1069
|
+
true
|
1070
|
+
|
1071
|
+
elsif input_string.include?("--multiline_comment")
|
1072
|
+
|
1073
|
+
true
|
1074
|
+
|
1075
|
+
else
|
1076
|
+
|
1077
|
+
false
|
1078
|
+
|
1079
|
+
end
|
1080
|
+
|
1081
|
+
end
|
1082
|
+
|
1083
|
+
reject_regexp = /(function |if |else|switch |case|while |for )/
|
1084
|
+
|
1085
|
+
modified_file_contents = []
|
1086
|
+
|
1087
|
+
input_file_contents.each do |line|
|
1088
|
+
|
1089
|
+
if line.index(reject_regexp) == nil
|
1090
|
+
|
1091
|
+
if !comment(line)
|
1092
|
+
|
1093
|
+
if !line.lstrip.eql?("")
|
1094
|
+
|
1095
|
+
if !line.lstrip.eql?("}\n")
|
1096
|
+
|
1097
|
+
if !line.lstrip.eql?("}\n\n")
|
1098
|
+
|
1099
|
+
modified_file_contents << line.rstrip + ";\n\n"
|
1100
|
+
|
1101
|
+
else
|
1102
|
+
|
1103
|
+
modified_file_contents << line
|
1104
|
+
|
1105
|
+
end
|
1106
|
+
|
1107
|
+
else
|
1108
|
+
|
1109
|
+
modified_file_contents << line
|
1110
|
+
|
1111
|
+
end
|
1112
|
+
|
1113
|
+
else
|
1114
|
+
|
1115
|
+
modified_file_contents << line
|
1116
|
+
|
1117
|
+
end
|
1118
|
+
|
1119
|
+
else
|
1120
|
+
|
1121
|
+
modified_file_contents << line
|
1122
|
+
|
1123
|
+
end
|
1124
|
+
|
1125
|
+
else
|
1126
|
+
|
1127
|
+
modified_file_contents << line
|
1128
|
+
|
1129
|
+
end
|
1130
|
+
|
1131
|
+
end
|
1132
|
+
|
1133
|
+
modified_file_contents
|
1134
|
+
|
1135
|
+
end
|
1136
|
+
|
1137
|
+
def pretty_print_javascript(javascript_file_contents,temporary_nila_file)
|
1138
|
+
|
1139
|
+
def reset_tabs(input_file_contents)
|
1140
|
+
|
1141
|
+
#This method removes all the predefined tabs to avoid problems in
|
1142
|
+
#later parts of the beautifying process.
|
1143
|
+
|
1144
|
+
for x in 0...input_file_contents.length
|
1145
|
+
|
1146
|
+
current_row = input_file_contents[x]
|
1147
|
+
|
1148
|
+
if !current_row.eql?("\n")
|
1149
|
+
|
1150
|
+
current_row = current_row.lstrip
|
1151
|
+
|
1152
|
+
end
|
1153
|
+
|
1154
|
+
input_file_contents[x] = current_row
|
1155
|
+
|
1156
|
+
|
1157
|
+
end
|
1158
|
+
|
1159
|
+
return input_file_contents
|
1160
|
+
|
1161
|
+
end
|
1162
|
+
|
1163
|
+
def find_all_matching_indices(input_string,pattern)
|
1164
|
+
|
1165
|
+
locations = []
|
1166
|
+
|
1167
|
+
index = input_string.index(pattern)
|
1168
|
+
|
1169
|
+
while index != nil
|
1170
|
+
|
1171
|
+
locations << index
|
1172
|
+
|
1173
|
+
index = input_string.index(pattern,index+1)
|
1174
|
+
|
1175
|
+
|
1176
|
+
end
|
1177
|
+
|
1178
|
+
return locations
|
1179
|
+
|
1180
|
+
|
1181
|
+
end
|
1182
|
+
|
1183
|
+
def convert_string_to_array(input_string,temporary_nila_file)
|
1184
|
+
|
1185
|
+
file_id = open(temporary_nila_file, 'w')
|
1186
|
+
|
1187
|
+
file_id.write(input_string)
|
1188
|
+
|
1189
|
+
file_id.close()
|
1190
|
+
|
1191
|
+
line_by_line_contents = read_file_line_by_line(temporary_nila_file)
|
1192
|
+
|
1193
|
+
return line_by_line_contents
|
1194
|
+
|
1195
|
+
end
|
1196
|
+
|
1197
|
+
def previous_formatting(input_string,tab_counter,temporary_nila_file)
|
1198
|
+
|
1199
|
+
string_as_array = convert_string_to_array(input_string,temporary_nila_file)
|
1200
|
+
|
1201
|
+
modified_array = []
|
1202
|
+
|
1203
|
+
string_as_array.each do |line|
|
1204
|
+
|
1205
|
+
modified_array << " "*tab_counter + line
|
1206
|
+
|
1207
|
+
end
|
1208
|
+
|
1209
|
+
return modified_array.join
|
1210
|
+
|
1211
|
+
end
|
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
|
+
|
1302
|
+
javascript_regexp = /(if |while |function |function\()/
|
1303
|
+
|
1304
|
+
locations = []
|
1305
|
+
|
1306
|
+
javascript_file_contents = reset_tabs(javascript_file_contents)
|
1307
|
+
|
1308
|
+
joined_file_contents = javascript_file_contents.join
|
1309
|
+
|
1310
|
+
code_block_starting_locations = find_all_matching_indices(joined_file_contents,javascript_regexp)
|
1311
|
+
|
1312
|
+
code_block_ending_locations = find_all_matching_indices(joined_file_contents,"}")
|
1313
|
+
|
1314
|
+
combined_location = [code_block_starting_locations,code_block_ending_locations.dup].flatten.sort
|
1315
|
+
|
1316
|
+
self_invoking_function_extract = joined_file_contents[code_block_starting_locations[0]..code_block_ending_locations[-1]]
|
1317
|
+
|
1318
|
+
self_invoking_function_array = convert_string_to_array(self_invoking_function_extract,temporary_nila_file)
|
1319
|
+
|
1320
|
+
combined_location.delete_at(0); combined_location.delete_at(-1); code_block_ending_locations.delete_at(-1); code_block_starting_locations.delete_at(0)
|
1321
|
+
|
1322
|
+
modified_self_invoking_array = self_invoking_function_array.dup
|
1323
|
+
|
1324
|
+
for x in 1...self_invoking_function_array.length-1
|
1325
|
+
|
1326
|
+
modified_self_invoking_array[x] = " " + self_invoking_function_array[x]
|
1327
|
+
|
1328
|
+
end
|
1329
|
+
|
1330
|
+
modified_self_invoking_array[-1] = "\n\n" + modified_self_invoking_array[-1]
|
1331
|
+
|
1332
|
+
nested_elements = []
|
1333
|
+
|
1334
|
+
nested_indices = []
|
1335
|
+
|
1336
|
+
modified_starting_locations = code_block_starting_locations.dup
|
1337
|
+
|
1338
|
+
while code_block_ending_locations.length > 0
|
1339
|
+
|
1340
|
+
matching_location = combined_location[combined_location.index(code_block_ending_locations[0])-1]
|
1341
|
+
|
1342
|
+
combined_location.delete(matching_location)
|
1343
|
+
|
1344
|
+
location_among_start_locations = code_block_starting_locations.index(matching_location)
|
1345
|
+
|
1346
|
+
if location_among_start_locations == 0
|
1347
|
+
|
1348
|
+
locations << [[matching_location,combined_location[combined_location.index(code_block_ending_locations[0])]]]
|
1349
|
+
|
1350
|
+
else
|
1351
|
+
|
1352
|
+
nested_elements << [matching_location,combined_location[combined_location.index(code_block_ending_locations[0])]]
|
1353
|
+
|
1354
|
+
nested_indices << modified_starting_locations.index(matching_location)
|
1355
|
+
|
1356
|
+
end
|
1357
|
+
|
1358
|
+
combined_location.delete(code_block_ending_locations[0])
|
1359
|
+
|
1360
|
+
code_block_ending_locations.delete_at(0)
|
1361
|
+
|
1362
|
+
code_block_starting_locations.delete(matching_location)
|
1363
|
+
|
1364
|
+
end
|
1365
|
+
|
1366
|
+
nested_indices.each_with_index do |loc,index|
|
1367
|
+
|
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
|
+
|
1379
|
+
|
1380
|
+
end
|
1381
|
+
|
1382
|
+
modified_locations = []
|
1383
|
+
|
1384
|
+
locations.each do |loc|
|
1385
|
+
|
1386
|
+
modified_locations << loc.sort
|
1387
|
+
|
1388
|
+
end
|
1389
|
+
|
1390
|
+
modified_joined_file_contents = joined_file_contents.dup
|
1391
|
+
|
1392
|
+
modified_joined_file_contents = modified_joined_file_contents.sub(self_invoking_function_extract,modified_self_invoking_array.join)
|
1393
|
+
|
1394
|
+
modified_locations.each do |location|
|
1395
|
+
|
1396
|
+
soft_tabs_counter = 2
|
1397
|
+
|
1398
|
+
location.each do |sublocation|
|
1399
|
+
|
1400
|
+
string_extract = joined_file_contents[sublocation[0]..sublocation[1]]
|
1401
|
+
|
1402
|
+
string_extract_array = convert_string_to_array(string_extract,temporary_nila_file)
|
1403
|
+
|
1404
|
+
if soft_tabs_counter > 1
|
1405
|
+
|
1406
|
+
string_extract_array[0] = " "*(soft_tabs_counter-1) + string_extract_array[0]
|
1407
|
+
|
1408
|
+
string_extract_array[-1] = " "*(soft_tabs_counter-1) + string_extract_array[-1]
|
1409
|
+
|
1410
|
+
end
|
1411
|
+
|
1412
|
+
for x in 1...string_extract_array.length-1
|
1413
|
+
|
1414
|
+
string_extract_array[x] = " "*soft_tabs_counter + string_extract_array[x]
|
1415
|
+
|
1416
|
+
end
|
1417
|
+
|
1418
|
+
if soft_tabs_counter > 1
|
1419
|
+
|
1420
|
+
modified_joined_file_contents = modified_joined_file_contents.sub(previous_formatting(string_extract,soft_tabs_counter-1,temporary_nila_file),string_extract_array.join)
|
1421
|
+
|
1422
|
+
else
|
1423
|
+
|
1424
|
+
modified_joined_file_contents = modified_joined_file_contents.sub(string_extract,string_extract_array.join)
|
1425
|
+
|
1426
|
+
end
|
1427
|
+
|
1428
|
+
soft_tabs_counter += 1
|
1429
|
+
|
1430
|
+
end
|
1431
|
+
|
1432
|
+
end
|
1433
|
+
|
1434
|
+
file_id = open(temporary_nila_file, 'w')
|
1435
|
+
|
1436
|
+
file_id.write(modified_joined_file_contents)
|
1437
|
+
|
1438
|
+
file_id.close()
|
1439
|
+
|
1440
|
+
line_by_line_contents = read_file_line_by_line(temporary_nila_file)
|
1441
|
+
|
1442
|
+
line_by_line_contents = fix_newlines(line_by_line_contents)
|
1443
|
+
|
1444
|
+
return line_by_line_contents
|
1445
|
+
|
1446
|
+
end
|
1447
|
+
|
1448
|
+
def pretty_print_nila(input_file_contents)
|
1449
|
+
|
1450
|
+
#Implementation is pending
|
1451
|
+
|
1452
|
+
end
|
1453
|
+
|
1454
|
+
def static_analysis(input_file_contents)
|
1455
|
+
|
1456
|
+
#Implementation is pending
|
1457
|
+
|
1458
|
+
end
|
1459
|
+
|
1460
|
+
def create_self_invoking_function(input_file_contents)
|
1461
|
+
|
1462
|
+
# A feature imported from Coffeescript. This makes all the function private by default
|
1463
|
+
# and prevents global variables from leaking.
|
1464
|
+
|
1465
|
+
modified_file_contents = ["(function() {\n",input_file_contents,"\n}).call(this);"].flatten
|
1466
|
+
|
1467
|
+
return modified_file_contents
|
1468
|
+
|
1469
|
+
end
|
1470
|
+
|
1471
|
+
def output_javascript(file_contents,output_file,temporary_nila_file)
|
1472
|
+
|
1473
|
+
file_id = open(output_file, 'w')
|
1474
|
+
|
1475
|
+
File.delete(temporary_nila_file)
|
1476
|
+
|
1477
|
+
file_id.write("//Written in Nila 0.0.3.2. Visit http://adhithyan15.github.io/nila\n")
|
1478
|
+
|
1479
|
+
file_id.write(file_contents.join)
|
1480
|
+
|
1481
|
+
file_id.close()
|
1482
|
+
|
1483
|
+
end
|
1484
|
+
|
1485
|
+
if File.exist?(input_file_path)
|
1486
|
+
|
1487
|
+
file_contents = read_file_line_by_line(input_file_path)
|
1488
|
+
|
1489
|
+
file_contents = extract_parsable_file(file_contents)
|
1490
|
+
|
1491
|
+
file_contents,multiline_comments,temp_file,output_js_file = replace_multiline_comments(file_contents,input_file_path,*output_file_name)
|
1492
|
+
|
1493
|
+
file_contents = split_semicolon_seperated_expressions(file_contents)
|
1494
|
+
|
1495
|
+
file_contents = compile_interpolated_strings(file_contents)
|
1496
|
+
|
1497
|
+
file_contents,singleline_comments = replace_singleline_comments(file_contents)
|
1498
|
+
|
1499
|
+
file_contents,named_functions,nested_functions = replace_named_functions(file_contents,temp_file)
|
1500
|
+
|
1501
|
+
comments = [singleline_comments,multiline_comments]
|
1502
|
+
|
1503
|
+
list_of_variables,file_contents = get_variables(file_contents,temp_file)
|
1504
|
+
|
1505
|
+
file_contents = compile_arrays(file_contents)
|
1506
|
+
|
1507
|
+
file_contents = compile_conditional_structures(file_contents,temp_file)
|
1508
|
+
|
1509
|
+
file_contents, function_names = compile_named_functions(file_contents,named_functions,nested_functions,temp_file)
|
1510
|
+
|
1511
|
+
file_contents, ruby_functions = compile_custom_function_map(file_contents)
|
1512
|
+
|
1513
|
+
function_names << ruby_functions
|
1514
|
+
|
1515
|
+
file_contents = compile_whitespace_delimited_functions(file_contents,function_names,temp_file)
|
1516
|
+
|
1517
|
+
file_contents = remove_question_marks(file_contents,list_of_variables,temp_file)
|
1518
|
+
|
1519
|
+
file_contents = add_semicolons(file_contents)
|
1520
|
+
|
1521
|
+
file_contents = compile_comments(file_contents,comments,temp_file)
|
1522
|
+
|
1523
|
+
file_contents = create_self_invoking_function(file_contents)
|
1524
|
+
|
1525
|
+
file_contents = pretty_print_javascript(file_contents,temp_file)
|
1526
|
+
|
1527
|
+
output_javascript(file_contents,output_js_file,temp_file)
|
1528
|
+
|
1529
|
+
puts "Compilation is successful!"
|
1530
|
+
|
1531
|
+
else
|
1532
|
+
|
1533
|
+
puts "File doesn't exist!"
|
1534
|
+
|
1535
|
+
end
|
1536
|
+
|
1537
|
+
end
|
1538
|
+
|
1539
|
+
def create_mac_executable(input_file)
|
1540
|
+
|
1541
|
+
def read_file_line_by_line(input_path)
|
1542
|
+
|
1543
|
+
file_id = open(input_path)
|
1544
|
+
|
1545
|
+
file_line_by_line = file_id.readlines()
|
1546
|
+
|
1547
|
+
file_id.close
|
1548
|
+
|
1549
|
+
return file_line_by_line
|
1550
|
+
|
1551
|
+
end
|
1552
|
+
|
1553
|
+
mac_file_contents = ["#!/usr/bin/env ruby"] + read_file_line_by_line(input_file)
|
1554
|
+
|
1555
|
+
mac_file_path = input_file.sub(".rb","")
|
1556
|
+
|
1557
|
+
file_id = open(mac_file_path,"w")
|
1558
|
+
|
1559
|
+
file_id.write(mac_file_contents.join)
|
1560
|
+
|
1561
|
+
file_id.close
|
1562
|
+
|
1563
|
+
end
|
1564
|
+
|
1565
|
+
def find_file_name(input_path,file_extension)
|
1566
|
+
|
1567
|
+
extension_remover = input_path.split(file_extension)
|
1568
|
+
|
1569
|
+
remaining_string = extension_remover[0].reverse
|
1570
|
+
|
1571
|
+
path_finder = remaining_string.index("/")
|
1572
|
+
|
1573
|
+
remaining_string = remaining_string.reverse
|
1574
|
+
|
1575
|
+
return remaining_string[remaining_string.length-path_finder..-1]
|
1576
|
+
|
1577
|
+
end
|
1578
|
+
|
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
|
1584
|
+
|
1585
|
+
opts = opts.to_hash
|
1586
|
+
|
1587
|
+
if opts[:compile] != nil
|
1588
|
+
|
1589
|
+
if opts[:compile].length == 1
|
1590
|
+
|
1591
|
+
input = opts[:compile][0]
|
1592
|
+
|
1593
|
+
if input.include? ".nila"
|
1594
|
+
|
1595
|
+
current_directory = Dir.pwd
|
1596
|
+
|
1597
|
+
input_file = input
|
1598
|
+
|
1599
|
+
file_path = current_directory + "/" + input_file
|
1600
|
+
|
1601
|
+
compile(file_path)
|
1602
|
+
|
1603
|
+
elsif input.include? "/"
|
1604
|
+
|
1605
|
+
folder_path = input
|
1606
|
+
|
1607
|
+
files = Dir.glob(File.join(folder_path, "*"))
|
1608
|
+
|
1609
|
+
files = files.reject {|path| !path.include? ".nila"}
|
1610
|
+
|
1611
|
+
files.each do |file|
|
1612
|
+
|
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]
|
1624
|
+
|
1625
|
+
output = opts[:compile][1]
|
1626
|
+
|
1627
|
+
if input.include? ".nila" and output.include? ".js"
|
1628
|
+
|
1629
|
+
input_file = input
|
1630
|
+
|
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
|
1666
|
+
|
1667
|
+
end
|
1668
|
+
|
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
|