nilac 0.0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/bin/nilac ADDED
@@ -0,0 +1,1741 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ #Nilac is the official Nila compiler. It compiles Nila into pure Javascript. Nilac is currently
5
+ #written in Ruby but will be self hosted in the upcoming years. Nila targets mostly the
6
+ #Node.js developers rather than client side developers.
7
+
8
+ #Nila was created by Adhithya Rajasekaran and Nilac is maintained by Adhithya Rajasekaran and Sri Madhavi Rajasekaran
9
+
10
+ require 'optparse'
11
+
12
+ def compile(input_file_path)
13
+
14
+ def read_file_line_by_line(input_path)
15
+
16
+ file_id = open(input_path)
17
+
18
+ file_line_by_line = file_id.readlines()
19
+
20
+ file_id.close
21
+
22
+ return file_line_by_line
23
+
24
+ end
25
+
26
+ def extract_parsable_array(input_file_contents)
27
+
28
+ #This method finds and removes the __END__ keyword and the following lines in a Nila file.
29
+
30
+ modified_file_contents = input_file_contents.dup
31
+
32
+ end_index = 0
33
+
34
+ input_file_contents.each_with_index do |line,index|
35
+
36
+ if line.strip.eql?("__END__")
37
+
38
+ end_index = index
39
+
40
+ end
41
+
42
+ end
43
+
44
+ if end_index == 0
45
+
46
+ output = modified_file_contents
47
+
48
+ else
49
+
50
+ output = modified_file_contents[0..end_index-1]
51
+
52
+ while output[-1].eql?("\n")
53
+
54
+ output.delete_at(-1)
55
+
56
+ end
57
+
58
+ end
59
+
60
+ return output
61
+
62
+ end
63
+
64
+ def replace_multiline_comments(input_file_contents,nila_file_path)
65
+
66
+ #This method will replace both the single and multiline comments
67
+ #
68
+ #Single line comment will be replaced by => --single_line_comment[n]
69
+ #
70
+ #Multiline comment will be replaced by => --multiline_comment[n]
71
+
72
+ def find_all_matching_indices(input_string,pattern)
73
+
74
+ locations = []
75
+
76
+ index = input_string.index(pattern)
77
+
78
+ while index != nil
79
+
80
+ locations << index
81
+
82
+ index = input_string.index(pattern,index+1)
83
+
84
+
85
+ end
86
+
87
+ return locations
88
+
89
+
90
+ end
91
+
92
+ def find_file_path(input_path,file_extension)
93
+
94
+ extension_remover = input_path.split(file_extension)
95
+
96
+ remaining_string = extension_remover[0].reverse
97
+
98
+ path_finder = remaining_string.index("/")
99
+
100
+ remaining_string = remaining_string.reverse
101
+
102
+ return remaining_string[0...remaining_string.length-path_finder]
103
+
104
+ end
105
+
106
+ def find_file_name(input_path,file_extension)
107
+
108
+ extension_remover = input_path.split(file_extension)
109
+
110
+ remaining_string = extension_remover[0].reverse
111
+
112
+ path_finder = remaining_string.index("/")
113
+
114
+ remaining_string = remaining_string.reverse
115
+
116
+ return remaining_string[remaining_string.length-path_finder..-1]
117
+
118
+ end
119
+
120
+ multiline_comments = []
121
+
122
+ file_contents_as_string = input_file_contents.join
123
+
124
+ modified_file_contents = file_contents_as_string.dup
125
+
126
+ multiline_comment_counter = 1
127
+
128
+ multiline_comments_start = find_all_matching_indices(file_contents_as_string,"=begin")
129
+
130
+ multiline_comments_end = find_all_matching_indices(file_contents_as_string,"=end")
131
+
132
+ for y in 0...multiline_comments_start.length
133
+
134
+ start_of_multiline_comment = multiline_comments_start[y]
135
+
136
+ end_of_multiline_comment = multiline_comments_end[y]
137
+
138
+ multiline_comment = file_contents_as_string[start_of_multiline_comment..end_of_multiline_comment+3]
139
+
140
+ modified_file_contents = modified_file_contents.gsub(multiline_comment,"--multiline_comment[#{multiline_comment_counter}]")
141
+
142
+ multiline_comment_counter += 1
143
+
144
+ multiline_comments << multiline_comment
145
+
146
+
147
+ end
148
+
149
+ temporary_nila_file = find_file_path(nila_file_path,".nila") + "temp_nila.nila"
150
+
151
+ output_js_file = find_file_path(nila_file_path,".nila") + find_file_name(nila_file_path,".nila") + ".js"
152
+
153
+ file_id = open(temporary_nila_file, 'w')
154
+
155
+ file_id2 = open(output_js_file, 'w')
156
+
157
+ file_id.write(modified_file_contents)
158
+
159
+ file_id2.write("//Written in Nila and compiled to Javascript. Have fun!\n\n")
160
+
161
+ file_id.close()
162
+
163
+ file_id2.close()
164
+
165
+ line_by_line_contents = read_file_line_by_line(temporary_nila_file)
166
+
167
+ comments = multiline_comments.dup
168
+
169
+ return line_by_line_contents,comments,temporary_nila_file,output_js_file
170
+
171
+ end
172
+
173
+ def split_semicolon_seperated_expressions(input_file_contents)
174
+
175
+ modified_file_contents = input_file_contents.dup
176
+
177
+ input_file_contents.each_with_index do |line,index|
178
+
179
+ if line.include?("\"")
180
+
181
+ first_index = line.index("\"")
182
+
183
+ modified_line = line.sub(line[first_index..line.index("\"",first_index+1)],"--string")
184
+
185
+ elsif line.include?("'")
186
+
187
+ first_index = line.index("'")
188
+
189
+ modified_line = line.sub(line[first_index..line.index("'",first_index+1)],"--string")
190
+
191
+ else
192
+
193
+ modified_line = line
194
+
195
+ end
196
+
197
+ if modified_line.include?(";")
198
+
199
+ replacement_line = modified_file_contents[index]
200
+
201
+ replacement_line = replacement_line.split(";").join("\n\n")
202
+
203
+ modified_file_contents[index] = replacement_line
204
+
205
+ end
206
+
207
+ end
208
+
209
+ return modified_file_contents
210
+
211
+ end
212
+
213
+ def compile_heredoc_strings(input_file_contents,temporary_nila_file)
214
+
215
+ #This method will compile all the Heredoc strings in Nila into pure
216
+ #Javascript strings. Ruby has two types of Heredocs. Currently, Nila doesn't support both of them.
217
+ #Here is an example of what Nila supports
218
+
219
+ #long_passage = <<-ipsumtext
220
+ #
221
+ #Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
222
+ #incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud
223
+ #exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute
224
+ #irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
225
+ #pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
226
+ #deserunt mollit anim id est laborum.
227
+ #
228
+ #ipsumtext
229
+
230
+ #Heredocs preserve all the formatting
231
+
232
+ def find_all_matching_indices(input_string,pattern)
233
+
234
+ locations = []
235
+
236
+ index = input_string.index(pattern)
237
+
238
+ while index != nil
239
+
240
+ locations << index
241
+
242
+ index = input_string.index(pattern,index+1)
243
+
244
+
245
+ end
246
+
247
+ return locations
248
+
249
+
250
+ end
251
+
252
+ joined_file_contents = input_file_contents.join
253
+
254
+ modified_file_contents = joined_file_contents.dup
255
+
256
+ heredoc_start_locations = find_all_matching_indices(joined_file_contents,"<<-")
257
+
258
+ heredoc_start_locations.each do |location|
259
+
260
+ string_extract = joined_file_contents[location..-1]
261
+
262
+ end_of_first_line = string_extract.index("\n")
263
+
264
+ name_of_heredoc = string_extract[3...end_of_first_line].rstrip
265
+
266
+ heredoc_start,heredoc_end = find_all_matching_indices(string_extract,name_of_heredoc)
267
+
268
+ heredoc = string_extract[heredoc_start..heredoc_end+name_of_heredoc.length-1]
269
+
270
+ heredoc_content = heredoc.split(name_of_heredoc)
271
+
272
+ heredoc_content = heredoc_content[1].lstrip.rstrip.gsub("\n","\\n").gsub("\t","\\t")
273
+
274
+ modified_file_contents = modified_file_contents.sub(string_extract[heredoc_start-3..heredoc_end+name_of_heredoc.length-1],"\""+heredoc_content+"\"")
275
+
276
+ end
277
+
278
+ file_id = open(temporary_nila_file, 'w')
279
+
280
+ file_id.write(modified_file_contents)
281
+
282
+ file_id.close()
283
+
284
+ line_by_line_contents = read_file_line_by_line(temporary_nila_file)
285
+
286
+ return line_by_line_contents
287
+
288
+ end
289
+
290
+ def compile_interpolated_strings(input_file_contents)
291
+
292
+ modified_file_contents = input_file_contents.dup
293
+
294
+ input_file_contents.each_with_index do |line,index|
295
+
296
+ if line.include?("\#{")
297
+
298
+ interpolated_strings = line.scan(/\#{\S{1,}}/)
299
+
300
+ interpolated_strings.each do |interpol|
301
+
302
+ string_split = line.split(interpol)
303
+
304
+ if string_split[1].eql?("\"\n")
305
+
306
+ replacement_string = "\" + " + interpol[2...-1]
307
+
308
+ modified_file_contents[index] = modified_file_contents[index].sub(interpol+"\"",replacement_string)
309
+
310
+ elsif string_split[1].eql?("\")\n")
311
+
312
+ replacement_string = "\" + " + interpol[2...-1]
313
+
314
+ modified_file_contents[index] = modified_file_contents[index].sub(interpol+"\"",replacement_string)
315
+
316
+ else
317
+
318
+ replacement_string = "\" + " + interpol[2...-1] + " + \""
319
+
320
+ modified_file_contents[index] = modified_file_contents[index].sub(interpol,replacement_string)
321
+
322
+ end
323
+
324
+ end
325
+
326
+ end
327
+
328
+ end
329
+
330
+ return modified_file_contents
331
+
332
+ end
333
+
334
+ def replace_singleline_comments(input_file_contents)
335
+
336
+ single_line_comments = []
337
+
338
+ singleline_comment_counter = 1
339
+
340
+ for x in 0...input_file_contents.length
341
+
342
+ current_row = input_file_contents[x]
343
+
344
+ if current_row.include?("#")
345
+
346
+ comment_start = current_row.index("#")
347
+
348
+ if current_row[comment_start+1] != "{"
349
+
350
+ comment = current_row[comment_start..-1]
351
+
352
+ single_line_comments << comment
353
+
354
+ current_row = current_row.gsub(comment,"--single_line_comment[#{singleline_comment_counter}]")
355
+
356
+ singleline_comment_counter += 1
357
+
358
+ end
359
+
360
+ end
361
+
362
+ input_file_contents[x] = current_row
363
+
364
+ end
365
+
366
+ return input_file_contents,single_line_comments
367
+
368
+ end
369
+
370
+ def replace_named_functions(nila_file_contents,temporary_nila_file)
371
+
372
+ def extract_array(input_array,start_index,end_index)
373
+
374
+ return input_array[start_index..end_index]
375
+
376
+ end
377
+
378
+ end_locations = []
379
+
380
+ key_word_locations = []
381
+
382
+ start_blocks = []
383
+
384
+ end_blocks = []
385
+
386
+ nila_regexp = /(def )/
387
+
388
+ named_code_blocks = []
389
+
390
+ for x in 0...nila_file_contents.length
391
+
392
+ current_row = nila_file_contents[x]
393
+
394
+ if current_row.index(nila_regexp) != nil
395
+
396
+ key_word_locations << x
397
+
398
+ elsif current_row.include?("end\n")
399
+
400
+ end_locations << x
401
+
402
+
403
+ end
404
+
405
+
406
+ end
407
+
408
+ modified_file_contents = nila_file_contents.dup
409
+
410
+ for y in 0...end_locations.length
411
+
412
+ current_location = end_locations[y]
413
+
414
+ current_string = modified_file_contents[current_location]
415
+
416
+ finder_location = current_location
417
+
418
+ while current_string.index(nila_regexp) == nil
419
+
420
+ finder_location -= 1
421
+
422
+ current_string = modified_file_contents[finder_location]
423
+
424
+ end
425
+
426
+ code_block_begin = finder_location
427
+
428
+ code_block_end = current_location
429
+
430
+ start_blocks << code_block_begin
431
+
432
+ end_blocks << code_block_end
433
+
434
+ code_block_begin_string_split = modified_file_contents[code_block_begin].split(" ")
435
+
436
+ code_block_begin_string_split[0] = code_block_begin_string_split[0].reverse
437
+
438
+ code_block_begin_string = code_block_begin_string_split.join(" ")
439
+
440
+ modified_file_contents[code_block_begin] = code_block_begin_string
441
+
442
+ end
443
+
444
+ final_modified_file_contents = nila_file_contents.dup
445
+
446
+ joined_file_contents = final_modified_file_contents.join
447
+
448
+ while start_blocks.length != 0
449
+
450
+ top_most_level = start_blocks.min
451
+
452
+ top_most_level_index = start_blocks.index(top_most_level)
453
+
454
+ matching_level = end_blocks[top_most_level_index]
455
+
456
+ named_code_blocks << extract_array(final_modified_file_contents,top_most_level,matching_level)
457
+
458
+ start_blocks.delete_at(top_most_level_index)
459
+
460
+ end_blocks.delete(matching_level)
461
+
462
+ end
463
+
464
+ codeblock_counter = 1
465
+
466
+ named_functions = named_code_blocks.dup
467
+
468
+ nested_functions = []
469
+
470
+ named_code_blocks.each do |codeblock|
471
+
472
+ if joined_file_contents.include?(codeblock.join)
473
+
474
+ joined_file_contents = joined_file_contents.sub(codeblock.join,"--named_function[#{codeblock_counter}]\n")
475
+
476
+ codeblock_counter += 1
477
+
478
+ nested_functions = nested_functions + [[]]
479
+
480
+ else
481
+
482
+ nested_functions[codeblock_counter-2] << codeblock
483
+
484
+ named_functions.delete(codeblock)
485
+
486
+ end
487
+
488
+ end
489
+
490
+ file_id = open(temporary_nila_file, 'w')
491
+
492
+ file_id.write(joined_file_contents)
493
+
494
+ file_id.close()
495
+
496
+ line_by_line_contents = read_file_line_by_line(temporary_nila_file)
497
+
498
+ return line_by_line_contents,named_functions,nested_functions
499
+
500
+
501
+ end
502
+
503
+ def get_variables(input_file_contents,temporary_nila_file)
504
+
505
+ #This method is solely focused on getting a list of variables to be declared.
506
+ #Since Javascript is a dynamic language, Nila doesn't have to worry about following up on those variables.
507
+
508
+ #Semicolons are required in Javascript for successful compilation. So this method adds semicolons at the end of each
509
+ #variable usage statements.
510
+
511
+ variables = []
512
+
513
+ for x in 0...input_file_contents.length
514
+
515
+ current_row = input_file_contents[x]
516
+
517
+ #The condition below verifies if the rows contain any equation operators.
518
+
519
+ if current_row.include?("=")
520
+
521
+ current_row = current_row.rstrip + "\n"
522
+
523
+ current_row_split = current_row.split("=")
524
+
525
+ for y in 0...current_row_split.length
526
+
527
+ current_row_split[y] = current_row_split[y].strip
528
+
529
+
530
+ end
531
+
532
+ variables << current_row_split[0]
533
+
534
+
535
+ end
536
+
537
+ input_file_contents[x] = current_row
538
+
539
+ end
540
+
541
+ file_contents_as_string = input_file_contents.join
542
+
543
+ file_id = open(temporary_nila_file, 'w')
544
+
545
+ file_id.write(file_contents_as_string)
546
+
547
+ file_id.close()
548
+
549
+ line_by_line_contents = read_file_line_by_line(temporary_nila_file)
550
+
551
+ variable_declaration_string = "var " + variables.uniq.join(", ") + "\n\n"
552
+
553
+ line_by_line_contents = [variable_declaration_string,line_by_line_contents].flatten
554
+
555
+ return variables.uniq,line_by_line_contents
556
+
557
+ end
558
+
559
+ def remove_question_marks(input_file_contents,variable_list,temporary_nila_file)
560
+
561
+ #A method to remove question marks from global variable names. Local variables are dealt
562
+ #with in their appropriate scope.
563
+
564
+ #Params:
565
+ #input_file_contents => An array containing the contents of the input nila file
566
+ #variable_list => An array containing all the global variables declared in the file
567
+ #temporary_nila_file => A file object used to write temporary contents
568
+
569
+ #Example:
570
+
571
+ #Nila
572
+ #isprime? = false
573
+
574
+ #Javascript Output
575
+ #var isprime;
576
+ #isprime = false;
577
+
578
+ #Returns a modified input_file_contents with all the question marks removed
579
+
580
+ joined_file_contents = input_file_contents.join
581
+
582
+ variable_list.each do |var|
583
+
584
+ if var.include? "?"
585
+
586
+ joined_file_contents = joined_file_contents.gsub(var,var[0...-1])
587
+
588
+ end
589
+
590
+ end
591
+
592
+ file_id = open(temporary_nila_file, 'w')
593
+
594
+ file_id.write(joined_file_contents)
595
+
596
+ file_id.close()
597
+
598
+ line_by_line_contents = read_file_line_by_line(temporary_nila_file)
599
+
600
+ return line_by_line_contents
601
+
602
+ end
603
+
604
+ def compile_arrays(input_file_contents)
605
+
606
+ #Currently the following kinds of array constructs are compilable
607
+
608
+ # 1. %w{} syntax
609
+ # 2. Range - Coming soon!
610
+
611
+ def extract(input_string,pattern_start,pattern_end)
612
+
613
+ def find_all_matching_indices(input_string,pattern)
614
+
615
+ locations = []
616
+
617
+ index = input_string.index(pattern)
618
+
619
+ while index != nil
620
+
621
+ locations << index
622
+
623
+ index = input_string.index(pattern,index+1)
624
+
625
+
626
+ end
627
+
628
+ return locations
629
+
630
+
631
+ end
632
+
633
+ all_start_locations = find_all_matching_indices(input_string,pattern_start)
634
+
635
+ all_end_locations = find_all_matching_indices(input_string,pattern_end)
636
+
637
+ pattern = []
638
+
639
+ all_start_locations.each_with_index do |location,index|
640
+
641
+ pattern << input_string[location..all_end_locations[index]]
642
+
643
+ end
644
+
645
+ return pattern
646
+
647
+ end
648
+
649
+ def compile_w_syntax(input_string)
650
+
651
+ modified_input_string = input_string[3...-1]
652
+
653
+ string_split = modified_input_string.split(" ")
654
+
655
+ return string_split.to_s
656
+
657
+ end
658
+
659
+ modified_file_contents = input_file_contents.dup
660
+
661
+ input_file_contents.each_with_index do |line,index|
662
+
663
+ if line.include?("%w{")
664
+
665
+ string_arrays = extract(line,"%w{","}")
666
+
667
+ string_arrays.each do |array|
668
+
669
+ modified_file_contents[index] = modified_file_contents[index].sub(array,compile_w_syntax(array))
670
+
671
+ end
672
+
673
+ end
674
+
675
+ end
676
+
677
+ return modified_file_contents
678
+
679
+ end
680
+
681
+ def compile_named_functions(input_file_contents,named_code_blocks,nested_functions,temporary_nila_file)
682
+
683
+ #This method compiles all the named Nila functions. Below is an example of what is meant
684
+ #by named/explicit function
685
+
686
+ #def square(input_number)
687
+ #
688
+ # return input_number*input_number
689
+ #
690
+ #end
691
+
692
+ #The above function will compile to
693
+
694
+ #function square(input_number) {
695
+ #
696
+ # return input_number*input_number;
697
+ #
698
+ # }
699
+
700
+ def is_parameterless?(input_function_block)
701
+
702
+ if input_function_block[0].include?("(")
703
+
704
+ false
705
+
706
+ else
707
+
708
+ true
709
+
710
+ end
711
+
712
+ end
713
+
714
+ def lexical_scoped_variables(input_function_block)
715
+
716
+ #This method will pickup and declare all the variables inside a function block. In future, this method will be
717
+ #merged with the get variables method
718
+
719
+ variables = []
720
+
721
+ input_function_block.each do |line|
722
+
723
+ if line.include? "="
724
+
725
+ current_line_split = line.strip.split("=")
726
+
727
+ variables << current_line_split[0].rstrip
728
+
729
+ end
730
+
731
+ end
732
+
733
+ variables.uniq
734
+
735
+ end
736
+
737
+ def remove_question_marks(input_file_contents,input_list,temporary_nila_file)
738
+
739
+ joined_file_contents = input_file_contents.join
740
+
741
+ input_list.each do |element|
742
+
743
+ if element.include? "?"
744
+
745
+ joined_file_contents = joined_file_contents.gsub(element,element[0...-1])
746
+
747
+ end
748
+
749
+ end
750
+
751
+ file_id = open(temporary_nila_file, 'w')
752
+
753
+ file_id.write(joined_file_contents)
754
+
755
+ file_id.close()
756
+
757
+ line_by_line_contents = read_file_line_by_line(temporary_nila_file)
758
+
759
+ return line_by_line_contents
760
+
761
+ end
762
+
763
+ def add_auto_return_statement(input_array)
764
+
765
+ joined_array = input_array.join
766
+
767
+ reversed_input_array = input_array.reverse
768
+
769
+ if !joined_array.include?("return ")
770
+
771
+ rejected_array = reversed_input_array.reject {|content| content.eql?("\n") || content.lstrip.eql?("}\n")}
772
+
773
+ last_statement = rejected_array[0]
774
+
775
+ replacement_string = "return #{last_statement.lstrip}"
776
+
777
+ input_array[input_array.index(last_statement)] = replacement_string
778
+
779
+ end
780
+
781
+ return input_array
782
+
783
+ end
784
+
785
+ def compile_function(input_array,temporary_nila_file)
786
+
787
+ modified_input_array = input_array.dup
788
+
789
+ if is_parameterless?(modified_input_array)
790
+
791
+ if modified_input_array[0].include?("--single")
792
+
793
+ modified_input_array[0] = input_array[0].sub "def","function"
794
+
795
+ interim_string = modified_input_array[0].split("--single")
796
+
797
+ modified_input_array[0] = interim_string[0].rstrip + "() {\n--single" + interim_string[1]
798
+
799
+
800
+ elsif modified_input_array[0].include?("--multi")
801
+
802
+ modified_input_array[0] = input_array[0].sub "def","function"
803
+
804
+ interim_string = modified_input_array[0].split("--multi")
805
+
806
+ modified_input_array[0] = interim_string[0].rstrip + "() {\n--multi" + interim_string[1]
807
+
808
+ else
809
+
810
+ modified_input_array[0] = input_array[0].sub "def","function"
811
+
812
+ modified_input_array[0] = modified_input_array[0].rstrip + "() {\n"
813
+
814
+ end
815
+
816
+ else
817
+
818
+ if modified_input_array[0].include?("--single")
819
+
820
+ modified_input_array[0] = input_array[0].sub "def","function"
821
+
822
+ interim_string = modified_input_array[0].split("--single")
823
+
824
+ modified_input_array[0] = interim_string[0].rstrip + " {\n--single" + interim_string[1]
825
+
826
+
827
+ elsif modified_input_array[0].include?("--multi")
828
+
829
+ modified_input_array[0] = input_array[0].sub "def","function"
830
+
831
+ interim_string = modified_input_array[0].split("--multi")
832
+
833
+ modified_input_array[0] = interim_string[0].rstrip + " {\n--multi" + interim_string[1]
834
+
835
+ else
836
+
837
+ modified_input_array[0] = input_array[0].sub "def","function"
838
+
839
+ modified_input_array[0] = modified_input_array[0].rstrip + " {\n"
840
+
841
+ end
842
+
843
+ end
844
+
845
+ modified_input_array[-1] = input_array[-1].sub "end","}\n"
846
+
847
+ variables = lexical_scoped_variables(modified_input_array)
848
+
849
+ if !variables.empty?
850
+
851
+ variable_string = "\nvar " + variables.join(", ") + "\n"
852
+
853
+ modified_input_array.insert(1,variable_string)
854
+
855
+ end
856
+
857
+ modified_input_array = remove_question_marks(modified_input_array,variables,temporary_nila_file)
858
+
859
+ modified_input_array = add_auto_return_statement(modified_input_array)
860
+
861
+ return modified_input_array
862
+
863
+ end
864
+
865
+ def extract_function_name(input_code_block)
866
+
867
+ first_line = input_code_block[0]
868
+
869
+ first_line_split = first_line.split(" ")
870
+
871
+ if first_line_split[1].include?("(")
872
+
873
+ function_name,parameters = first_line_split[1].split("(")
874
+
875
+ else
876
+
877
+ function_name = first_line_split[1]
878
+
879
+ end
880
+
881
+ return function_name
882
+
883
+ end
884
+
885
+ joined_file_contents = input_file_contents.join
886
+
887
+ codeblock_counter = 1
888
+
889
+ function_names = []
890
+
891
+ named_code_blocks.each do |codeblock|
892
+
893
+ function_names[codeblock_counter-1] = []
894
+
895
+ joined_file_contents = joined_file_contents.sub("--named_function[#{codeblock_counter}]\n",compile_function(codeblock,temporary_nila_file).join)
896
+
897
+ codeblock_counter += 1
898
+
899
+ current_nested_functions = nested_functions[codeblock_counter-2]
900
+
901
+ function_names[codeblock_counter-2] << extract_function_name(codeblock)
902
+
903
+ current_nested_functions.each do |nested_function|
904
+
905
+ function_names[codeblock_counter-2] << extract_function_name(nested_function)
906
+
907
+ joined_file_contents = joined_file_contents.sub(nested_function.join,compile_function(nested_function,temporary_nila_file).join)
908
+
909
+ end
910
+
911
+ end
912
+
913
+ file_id = open(temporary_nila_file, 'w')
914
+
915
+ file_id.write(joined_file_contents)
916
+
917
+ file_id.close()
918
+
919
+ line_by_line_contents = read_file_line_by_line(temporary_nila_file)
920
+
921
+ return line_by_line_contents,function_names
922
+
923
+ end
924
+
925
+ def compile_custom_function_map(input_file_contents)
926
+
927
+ function_map = ["puts"]
928
+
929
+ function_map_replacements = {
930
+
931
+ "puts" => "console.log"
932
+
933
+ }
934
+
935
+ modified_file_contents = input_file_contents.dup
936
+
937
+ input_file_contents.each_with_index do |line,index|
938
+
939
+ function_map.each do |function|
940
+
941
+ if line.include?(function+"(") or line.include?(function+" ")
942
+
943
+ modified_file_contents[index] = line.sub(function,function_map_replacements[function])
944
+
945
+ end
946
+
947
+ end
948
+
949
+ end
950
+
951
+ return modified_file_contents,function_map_replacements.values
952
+
953
+ end
954
+
955
+ def compile_whitespace_delimited_functions(input_file_contents,function_names,temporary_nila_file)
956
+
957
+ def extract(input_string,pattern_start,pattern_end)
958
+
959
+ def find_all_matching_indices(input_string,pattern)
960
+
961
+ locations = []
962
+
963
+ index = input_string.index(pattern)
964
+
965
+ while index != nil
966
+
967
+ locations << index
968
+
969
+ index = input_string.index(pattern,index+1)
970
+
971
+
972
+ end
973
+
974
+ return locations
975
+
976
+
977
+ end
978
+
979
+ all_start_locations = find_all_matching_indices(input_string,pattern_start)
980
+
981
+ pattern = []
982
+
983
+ all_start_locations.each do |location|
984
+
985
+ extracted_string = input_string[location..-1]
986
+
987
+ pattern << extracted_string[0..extracted_string.index(pattern_end)]
988
+
989
+ end
990
+
991
+
992
+ return pattern
993
+
994
+ end
995
+
996
+ joined_file_contents = input_file_contents.join
997
+
998
+ function_names.each do |list_of_functions|
999
+
1000
+ list_of_functions.each do |function|
1001
+
1002
+ matching_strings = extract(joined_file_contents,function+" ","\n")
1003
+
1004
+ matching_strings.each do |string|
1005
+
1006
+ modified_string = string.dup
1007
+
1008
+ modified_string = modified_string.sub(function+" ",function+"(")
1009
+
1010
+ modified_string = modified_string.sub("\n",")\n")
1011
+
1012
+ joined_file_contents = joined_file_contents.sub(string,modified_string)
1013
+
1014
+ end
1015
+
1016
+ end
1017
+
1018
+ end
1019
+
1020
+ file_id = open(temporary_nila_file, 'w')
1021
+
1022
+ file_id.write(joined_file_contents)
1023
+
1024
+ file_id.close()
1025
+
1026
+ line_by_line_contents = read_file_line_by_line(temporary_nila_file)
1027
+
1028
+ return line_by_line_contents
1029
+
1030
+ end
1031
+
1032
+ def compile_conditional_structures(input_file_contents,temporary_nila_file)
1033
+
1034
+ #Currently the following conditional structures have been implemented
1035
+
1036
+ #1. If, Elsif, Else Statement
1037
+
1038
+
1039
+
1040
+ end
1041
+
1042
+ def compile_comments(input_file_contents,comments,temporary_nila_file)
1043
+
1044
+ #This method converts Nila comments into pure Javascript comments. This method
1045
+ #handles both single line and multiline comments.
1046
+
1047
+ file_contents_as_string = input_file_contents.join
1048
+
1049
+ single_line_comments = comments[0]
1050
+
1051
+ multiline_comments = comments[1]
1052
+
1053
+ single_line_comment_counter = 1
1054
+
1055
+ multi_line_comment_counter = 1
1056
+
1057
+ for x in 0...single_line_comments.length
1058
+
1059
+ current_singleline_comment = "--single_line_comment[#{single_line_comment_counter}]"
1060
+
1061
+ replacement_singleline_string = single_line_comments[x].sub("#","//")
1062
+
1063
+ file_contents_as_string = file_contents_as_string.sub(current_singleline_comment,replacement_singleline_string)
1064
+
1065
+ single_line_comment_counter += 1
1066
+
1067
+
1068
+ end
1069
+
1070
+ for y in 0...multiline_comments.length
1071
+
1072
+ current_multiline_comment = "--multiline_comment[#{multi_line_comment_counter}]"
1073
+
1074
+ replacement_multiline_string = multiline_comments[y].sub("=begin","/*\n")
1075
+
1076
+ replacement_multiline_string = replacement_multiline_string.sub("=end","\n*/")
1077
+
1078
+ file_contents_as_string = file_contents_as_string.sub(current_multiline_comment,replacement_multiline_string)
1079
+
1080
+ multi_line_comment_counter += 1
1081
+
1082
+ end
1083
+
1084
+ file_id = open(temporary_nila_file, 'w')
1085
+
1086
+ file_id.write(file_contents_as_string)
1087
+
1088
+ file_id.close()
1089
+
1090
+ line_by_line_contents = read_file_line_by_line(temporary_nila_file)
1091
+
1092
+ line_by_line_contents
1093
+
1094
+ end
1095
+
1096
+ def add_semicolons(input_file_contents)
1097
+
1098
+ def comment(input_string)
1099
+
1100
+ if input_string.include?("--single_line_comment")
1101
+
1102
+ true
1103
+
1104
+ elsif input_string.include?("--multiline_comment")
1105
+
1106
+ true
1107
+
1108
+ else
1109
+
1110
+ false
1111
+
1112
+ end
1113
+
1114
+ end
1115
+
1116
+ reject_regexp = /(function |if |else|switch |case|while |for )/
1117
+
1118
+ modified_file_contents = []
1119
+
1120
+ input_file_contents.each do |line|
1121
+
1122
+ if line.index(reject_regexp) == nil
1123
+
1124
+ if !comment(line)
1125
+
1126
+ if !line.eql?("\n")
1127
+
1128
+ if !line.lstrip.eql?("}\n")
1129
+
1130
+ if !line.lstrip.eql?("}\n\n")
1131
+
1132
+ modified_file_contents << line.rstrip + ";\n\n"
1133
+
1134
+ else
1135
+
1136
+ modified_file_contents << line
1137
+
1138
+ end
1139
+
1140
+ else
1141
+
1142
+ modified_file_contents << line
1143
+
1144
+ end
1145
+
1146
+ else
1147
+
1148
+ modified_file_contents << line
1149
+
1150
+ end
1151
+
1152
+ else
1153
+
1154
+ modified_file_contents << line
1155
+
1156
+ end
1157
+
1158
+ else
1159
+
1160
+ modified_file_contents << line
1161
+
1162
+ end
1163
+
1164
+ end
1165
+
1166
+ modified_file_contents
1167
+
1168
+ end
1169
+
1170
+ def pretty_print_javascript(javascript_file_contents,temporary_nila_file)
1171
+
1172
+ def reset_tabs(input_file_contents)
1173
+
1174
+ #This method removes all the predefined tabs to avoid problems in
1175
+ #later parts of the beautifying process.
1176
+
1177
+ for x in 0...input_file_contents.length
1178
+
1179
+ current_row = input_file_contents[x]
1180
+
1181
+ if !current_row.eql?("\n")
1182
+
1183
+ current_row = current_row.lstrip
1184
+
1185
+ end
1186
+
1187
+ input_file_contents[x] = current_row
1188
+
1189
+
1190
+ end
1191
+
1192
+ return input_file_contents
1193
+
1194
+ end
1195
+
1196
+ def find_all_matching_indices(input_string,pattern)
1197
+
1198
+ locations = []
1199
+
1200
+ index = input_string.index(pattern)
1201
+
1202
+ while index != nil
1203
+
1204
+ locations << index
1205
+
1206
+ index = input_string.index(pattern,index+1)
1207
+
1208
+
1209
+ end
1210
+
1211
+ return locations
1212
+
1213
+
1214
+ end
1215
+
1216
+ def convert_string_to_array(input_string,temporary_nila_file)
1217
+
1218
+ file_id = open(temporary_nila_file, 'w')
1219
+
1220
+ file_id.write(input_string)
1221
+
1222
+ file_id.close()
1223
+
1224
+ line_by_line_contents = read_file_line_by_line(temporary_nila_file)
1225
+
1226
+ return line_by_line_contents
1227
+
1228
+ end
1229
+
1230
+ def previous_formatting(input_string,tab_counter,temporary_nila_file)
1231
+
1232
+ string_as_array = convert_string_to_array(input_string,temporary_nila_file)
1233
+
1234
+ modified_array = []
1235
+
1236
+ string_as_array.each do |line|
1237
+
1238
+ modified_array << " "*tab_counter + line
1239
+
1240
+ end
1241
+
1242
+ return modified_array.join
1243
+
1244
+ end
1245
+
1246
+ javascript_regexp = /(function |function\()/
1247
+
1248
+ locations = []
1249
+
1250
+ javascript_file_contents = reset_tabs(javascript_file_contents)
1251
+
1252
+ joined_file_contents = javascript_file_contents.join
1253
+
1254
+ code_block_starting_locations = find_all_matching_indices(joined_file_contents,javascript_regexp)
1255
+
1256
+ code_block_ending_locations = find_all_matching_indices(joined_file_contents,"}")
1257
+
1258
+ combined_location = [code_block_starting_locations,code_block_ending_locations.dup].flatten.sort
1259
+
1260
+ last_matching_location = 0
1261
+
1262
+ self_invoking_function_extract = joined_file_contents[code_block_starting_locations[0]..code_block_ending_locations[-1]]
1263
+
1264
+ self_invoking_function_array = convert_string_to_array(self_invoking_function_extract,temporary_nila_file)
1265
+
1266
+ combined_location.delete_at(0); combined_location.delete_at(-1); code_block_ending_locations.delete_at(-1); code_block_starting_locations.delete_at(0)
1267
+
1268
+ modified_self_invoking_array = self_invoking_function_array.dup
1269
+
1270
+ for x in 1...self_invoking_function_array.length-1
1271
+
1272
+ modified_self_invoking_array[x] = " " + self_invoking_function_array[x]
1273
+
1274
+ end
1275
+
1276
+ modified_self_invoking_array[-1] = "\n\n" + modified_self_invoking_array[-1]
1277
+
1278
+ while code_block_ending_locations.length > 0
1279
+
1280
+ matching_location = combined_location[combined_location.index(code_block_ending_locations[0])-1]
1281
+
1282
+ location_among_start_locations = code_block_starting_locations.index(matching_location)
1283
+
1284
+ locations << [[matching_location,combined_location[combined_location.index(code_block_ending_locations[0])]]]
1285
+
1286
+ code_block_ending_locations.delete_at(0)
1287
+
1288
+ if code_block_ending_locations.length > 0
1289
+
1290
+ for x in location_among_start_locations-1..last_matching_location
1291
+
1292
+ locations[-1] << [code_block_starting_locations[x],code_block_ending_locations[0]]
1293
+
1294
+ code_block_ending_locations.delete_at(0)
1295
+
1296
+ end
1297
+
1298
+ end
1299
+
1300
+ last_matching_location = location_among_start_locations + 1
1301
+
1302
+ end
1303
+
1304
+ modified_locations = []
1305
+
1306
+ locations.each do |loc|
1307
+
1308
+ modified_locations << loc.sort
1309
+
1310
+ end
1311
+
1312
+ modified_joined_file_contents = joined_file_contents.dup
1313
+
1314
+ modified_joined_file_contents = modified_joined_file_contents.sub(self_invoking_function_extract,modified_self_invoking_array.join)
1315
+
1316
+ modified_locations.each do |location|
1317
+
1318
+ soft_tabs_counter = 2
1319
+
1320
+ location.each do |sublocation|
1321
+
1322
+ string_extract = joined_file_contents[sublocation[0]..sublocation[1]]
1323
+
1324
+ string_extract_array = convert_string_to_array(string_extract,temporary_nila_file)
1325
+
1326
+ if soft_tabs_counter > 1
1327
+
1328
+ string_extract_array[0] = " "*(soft_tabs_counter-1) + string_extract_array[0]
1329
+
1330
+ string_extract_array[-1] = " "*(soft_tabs_counter-1) + string_extract_array[-1]
1331
+
1332
+ end
1333
+
1334
+ for x in 1...string_extract_array.length-1
1335
+
1336
+ string_extract_array[x] = " "*soft_tabs_counter + string_extract_array[x]
1337
+
1338
+ end
1339
+
1340
+ if soft_tabs_counter > 1
1341
+
1342
+ modified_joined_file_contents = modified_joined_file_contents.sub(previous_formatting(string_extract,soft_tabs_counter-1,temporary_nila_file),string_extract_array.join)
1343
+
1344
+ else
1345
+
1346
+ modified_joined_file_contents = modified_joined_file_contents.sub(string_extract,string_extract_array.join)
1347
+
1348
+ end
1349
+
1350
+ soft_tabs_counter += 1
1351
+
1352
+ end
1353
+
1354
+ end
1355
+
1356
+ file_id = open(temporary_nila_file, 'w')
1357
+
1358
+ file_id.write(modified_joined_file_contents)
1359
+
1360
+ file_id.close()
1361
+
1362
+ line_by_line_contents = read_file_line_by_line(temporary_nila_file)
1363
+
1364
+ var_declaration_index = 0
1365
+
1366
+ for x in 0...line_by_line_contents.length
1367
+
1368
+ current_row = line_by_line_contents[x]
1369
+
1370
+ if current_row.lstrip.include?("var ")
1371
+
1372
+ var_declaration_index = x
1373
+
1374
+ break
1375
+
1376
+ end
1377
+
1378
+ end
1379
+
1380
+ empty_check = line_by_line_contents[x+1..x+4]
1381
+
1382
+ empty_check.each_with_index do |content,index|
1383
+
1384
+ empty_check[index] = content.lstrip
1385
+
1386
+ end
1387
+
1388
+ empty_check = empty_check.delete_if {|content| content.empty?}
1389
+
1390
+ if empty_check.empty?
1391
+
1392
+ line_by_line_contents.delete_at(x+1);line_by_line_contents.delete_at(x+2)
1393
+
1394
+ end
1395
+
1396
+ return line_by_line_contents
1397
+
1398
+ end
1399
+
1400
+ def pretty_print_nila(input_file_contents)
1401
+
1402
+ #Implementation is pending
1403
+
1404
+ end
1405
+
1406
+ def static_analysis(input_file_contents)
1407
+
1408
+ #Implementation is pending
1409
+
1410
+ end
1411
+
1412
+ def create_self_invoking_function(input_file_contents)
1413
+
1414
+ # A feature imported from Coffeescript. This makes all the function private by default
1415
+ # and prevents global variables from leaking.
1416
+
1417
+ modified_file_contents = ["(function() {\n\n",input_file_contents,"\n\n}).call(this);\n"].flatten
1418
+
1419
+ return modified_file_contents
1420
+
1421
+ end
1422
+
1423
+ def compile_license_functions(input_file_contents,temporary_nila_file)
1424
+
1425
+ #This method will make it easier for developers to add open source licensing to their projects
1426
+
1427
+ #Currently the following licenses are supported
1428
+
1429
+ #1. MIT License
1430
+
1431
+ #Example of MIT License => mit_license(year,authors)
1432
+
1433
+ #mit_license("2013","Adhithya Rajasekaran, Sri Madhavi Rajasekaran")
1434
+
1435
+ def find_all_matching_indices(input_string,pattern)
1436
+
1437
+ locations = []
1438
+
1439
+ index = input_string.index(pattern)
1440
+
1441
+ while index != nil
1442
+
1443
+ locations << index
1444
+
1445
+ index = input_string.index(pattern,index+1)
1446
+
1447
+
1448
+ end
1449
+
1450
+ return locations
1451
+
1452
+
1453
+ end
1454
+
1455
+ license_functions = ["mit_license(","apache_license"]
1456
+
1457
+ mit_license = <<-licensetext
1458
+
1459
+ /*
1460
+
1461
+ Copyright yer, <auth>
1462
+
1463
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”),
1464
+ to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
1465
+ 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:
1466
+
1467
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
1468
+
1469
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1470
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1471
+ 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
1472
+ IN THE SOFTWARE.
1473
+
1474
+ */
1475
+
1476
+
1477
+ licensetext
1478
+
1479
+ apache_license = <<-licensetext
1480
+
1481
+ /*
1482
+
1483
+ Copyright [yer] [auth]
1484
+
1485
+ Licensed under the Apache License, Version 2.0 (the "License");
1486
+ you may not use this file except in compliance with the License.
1487
+ You may obtain a copy of the License at
1488
+
1489
+ http://www.apache.org/licenses/LICENSE-2.0
1490
+
1491
+ Unless required by applicable law or agreed to in writing, software
1492
+ distributed under the License is distributed on an "AS IS" BASIS,
1493
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1494
+ See the License for the specific language governing permissions and
1495
+ limitations under the License.
1496
+
1497
+ */
1498
+
1499
+
1500
+ licensetext
1501
+
1502
+ license_texts = [mit_license,apache_license]
1503
+
1504
+ license_params = [2,2]
1505
+
1506
+ license_replaceables = ["yer","auth","orgg"]
1507
+
1508
+ joined_file_contents = input_file_contents.join
1509
+
1510
+ license_functions.each_with_index do |function,index|
1511
+
1512
+ function_locations = find_all_matching_indices(joined_file_contents,function)
1513
+
1514
+ function_locations.each do |location|
1515
+
1516
+ string_extract = joined_file_contents[location..-1]
1517
+
1518
+ function_end = string_extract.index(")")
1519
+
1520
+ function_call = string_extract[0..function_end]
1521
+
1522
+ parameters = function_call.split(function)[1][0...-1]
1523
+
1524
+ parameters = parameters.split(":")
1525
+
1526
+ parameters.each_with_index do |param,index|
1527
+
1528
+ parameters[index] = param[1...-1]
1529
+
1530
+ end
1531
+
1532
+ replacement_string = license_texts[index]
1533
+
1534
+ for x in 0...parameters.length
1535
+
1536
+ replacement_string = replacement_string.sub(license_replaceables[x],parameters[x])
1537
+
1538
+ end
1539
+
1540
+ replacement_array = replacement_string.split("\n")
1541
+
1542
+ modified_replacement_array = replacement_array.dup
1543
+
1544
+ replacement_array.each_with_index do |line,index|
1545
+
1546
+ modified_replacement_array[index] = line.lstrip
1547
+
1548
+ end
1549
+
1550
+ replacement_string = replacement_array.join("\n")
1551
+
1552
+ if joined_file_contents.include?(function_call+";\n")
1553
+
1554
+ joined_file_contents = joined_file_contents.sub(function_call+";\n","")
1555
+
1556
+ else
1557
+
1558
+ joined_file_contents = joined_file_contents.sub(function_call+";","")
1559
+
1560
+ end
1561
+
1562
+ joined_file_contents = replacement_string.lstrip + "\n\n" + joined_file_contents
1563
+
1564
+ end
1565
+
1566
+ end
1567
+
1568
+ file_id = open(temporary_nila_file, 'w')
1569
+
1570
+ file_id.write(joined_file_contents)
1571
+
1572
+ file_id.close()
1573
+
1574
+ line_by_line_contents = read_file_line_by_line(temporary_nila_file)
1575
+
1576
+ return line_by_line_contents
1577
+
1578
+ end
1579
+
1580
+ def output_javascript(file_contents,output_file,temporary_nila_file)
1581
+
1582
+ file_id = open(output_file, 'w')
1583
+
1584
+ File.delete(temporary_nila_file)
1585
+
1586
+ file_id.write("// Generated by Nilac 0.0.1 Visit http://adhithyan15.github.com/nila to know more\n\n")
1587
+
1588
+ file_id.write(file_contents.join)
1589
+
1590
+ file_id.close()
1591
+
1592
+ end
1593
+
1594
+ file_contents = read_file_line_by_line(input_file_path)
1595
+
1596
+ file_contents = extract_parsable_array(file_contents)
1597
+
1598
+ file_contents,multiline_comments,temp_file,output_js_file = replace_multiline_comments(file_contents,input_file_path)
1599
+
1600
+ file_contents = split_semicolon_seperated_expressions(file_contents)
1601
+
1602
+ file_contents = compile_heredoc_strings(file_contents,temp_file)
1603
+
1604
+ file_contents = compile_interpolated_strings(file_contents)
1605
+
1606
+ file_contents,singleline_comments = replace_singleline_comments(file_contents)
1607
+
1608
+ file_contents,named_functions,nested_functions = replace_named_functions(file_contents,temp_file)
1609
+
1610
+ comments = [singleline_comments,multiline_comments]
1611
+
1612
+ list_of_variables,file_contents = get_variables(file_contents,temp_file)
1613
+
1614
+ file_contents = compile_arrays(file_contents)
1615
+
1616
+ file_contents, function_names = compile_named_functions(file_contents,named_functions,nested_functions,temp_file)
1617
+
1618
+ file_contents, ruby_functions = compile_custom_function_map(file_contents)
1619
+
1620
+ function_names << ruby_functions
1621
+
1622
+ file_contents = compile_whitespace_delimited_functions(file_contents,function_names,temp_file)
1623
+
1624
+ file_contents = remove_question_marks(file_contents,list_of_variables,temp_file)
1625
+
1626
+ file_contents = add_semicolons(file_contents)
1627
+
1628
+ file_contents = compile_comments(file_contents,comments,temp_file)
1629
+
1630
+ file_contents = create_self_invoking_function(file_contents)
1631
+
1632
+ file_contents = compile_license_functions(file_contents,temp_file)
1633
+
1634
+ file_contents = pretty_print_javascript(file_contents,temp_file)
1635
+
1636
+ output_javascript(file_contents,output_js_file,temp_file)
1637
+
1638
+
1639
+ end
1640
+
1641
+ def create_executable(input_file)
1642
+
1643
+ windows_output = `ocra --add-all-core #{input_file}`
1644
+
1645
+ end
1646
+
1647
+ def create_mac_executable(input_file)
1648
+
1649
+ def read_file_line_by_line(input_path)
1650
+
1651
+ file_id = open(input_path)
1652
+
1653
+ file_line_by_line = file_id.readlines()
1654
+
1655
+ file_id.close
1656
+
1657
+ return file_line_by_line
1658
+
1659
+ end
1660
+
1661
+ mac_file_contents = ["#!/usr/bin/env ruby"] + read_file_line_by_line(input_file)
1662
+
1663
+ mac_file_path = input_file.sub(".rb","")
1664
+
1665
+ file_id = open(mac_file_path,"w")
1666
+
1667
+ file_id.write(mac_file_contents.join)
1668
+
1669
+ file_id.close
1670
+
1671
+ end
1672
+
1673
+ def find_file_name(input_path,file_extension)
1674
+
1675
+ extension_remover = input_path.split(file_extension)
1676
+
1677
+ remaining_string = extension_remover[0].reverse
1678
+
1679
+ path_finder = remaining_string.index("\\")
1680
+
1681
+ remaining_string = remaining_string.reverse
1682
+
1683
+ return remaining_string[remaining_string.length-path_finder..-1]
1684
+
1685
+ end
1686
+
1687
+ options = {}
1688
+
1689
+ OptionParser.new do |opts|
1690
+ opts.banner = "Usage: nilac [options] nilafile"
1691
+
1692
+ opts.on("-c", "--compile FILE", "Compile to Javascript") do |file|
1693
+ current_directory = Dir.pwd
1694
+ file_path = current_directory + "/" + file
1695
+ compile(file_path)
1696
+ puts "Compilation Successful!"
1697
+
1698
+ end
1699
+
1700
+ opts.on("-r", "--run FILE", "Compile to Javascript and Run") do |file|
1701
+ current_directory = Dir.pwd
1702
+
1703
+ file_path = current_directory + "/" + file
1704
+
1705
+ compile(file_path)
1706
+
1707
+ js_file_name = find_file_name(file_path,".nila") + ".js"
1708
+
1709
+ node_output = `node #{js_file_name}`
1710
+
1711
+ puts node_output
1712
+
1713
+ end
1714
+
1715
+ opts.on("-b", "--build", "Builds Itself") do
1716
+
1717
+ create_executable("nilac.rb")
1718
+
1719
+ puts "Build Successful!"
1720
+
1721
+ end
1722
+
1723
+ opts.on("-m", "--buildmac", "Builds Mac Executables") do
1724
+
1725
+ file_path = Dir.pwd + "/nilac.rb"
1726
+
1727
+ create_mac_executable(file_path)
1728
+
1729
+ puts "Build Successful!"
1730
+
1731
+ end
1732
+
1733
+ opts.on("-v", "--version", "Version of Nilac") do
1734
+
1735
+ version_number = "0.0.1"
1736
+
1737
+ puts "Current Nilac Version: #{version_number}"
1738
+
1739
+ end
1740
+
1741
+ end.parse!