nilac 0.0.4.3.9.7.1 → 0.0.4.3.9.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -2
  3. data/Rakefile +1 -1
  4. data/cookbook/case_insensitive_compare.js +13 -0
  5. data/cookbook/case_insensitive_compare.nila +7 -0
  6. data/cookbook/compare_strings.js +13 -0
  7. data/cookbook/compare_strings.nila +7 -0
  8. data/cookbook/concat11.js +13 -0
  9. data/cookbook/concat11.nila +4 -0
  10. data/cookbook/concat12.js +23 -0
  11. data/cookbook/concat12.nila +15 -0
  12. data/cookbook/find_substring.js +15 -0
  13. data/cookbook/find_substring.nila +5 -0
  14. data/cookbook/string_interpolation.js +7 -0
  15. data/cookbook/string_interpolation.nila +1 -0
  16. data/cookbook/substring_extract.js +21 -0
  17. data/cookbook/substring_extract.nila +8 -0
  18. data/examples/my_file.js +5 -0
  19. data/examples/repl.js +0 -33
  20. data/examples/repl.nila +36 -8
  21. data/examples/temp_nila.nila +63 -0
  22. data/lib/nilac.rb +83 -68
  23. data/lib/nilac/add_line_numbers.rb +17 -0
  24. data/lib/nilac/add_semicolons.rb +13 -3
  25. data/lib/nilac/compile_arrays.rb +38 -5
  26. data/lib/nilac/compile_blocks.rb +87 -25
  27. data/lib/nilac/compile_case_statement.rb +4 -0
  28. data/lib/nilac/compile_chained_comparison.rb +35 -0
  29. data/lib/nilac/compile_comments.rb +9 -0
  30. data/lib/nilac/compile_conditional_structures.rb +26 -3
  31. data/lib/nilac/compile_custom_function_map.rb +24 -2
  32. data/lib/nilac/compile_hashes.rb +3 -1
  33. data/lib/nilac/compile_heredocs.rb +2 -0
  34. data/lib/nilac/compile_inline_for.rb +13 -0
  35. data/lib/nilac/compile_interpolated_strings.rb +184 -5
  36. data/lib/nilac/compile_lambdas.rb +24 -8
  37. data/lib/nilac/compile_new_keyword.rb +37 -0
  38. data/lib/nilac/compile_nilac_options.rb +79 -0
  39. data/lib/nilac/compile_parallel_assignment.rb +3 -1
  40. data/lib/nilac/compile_ranges.rb +60 -0
  41. data/lib/nilac/compile_require_statements.rb +4 -2
  42. data/lib/nilac/compile_ruby_math.rb +20 -0
  43. data/lib/nilac/compile_ruby_methods.rb +49 -0
  44. data/lib/nilac/compile_whitespace_delimited_functions.rb +15 -1
  45. data/lib/nilac/extract_paranthesis_contents.rb +37 -0
  46. data/lib/nilac/extract_strings.rb +63 -0
  47. data/lib/nilac/fix_javascript_traps.rb +89 -0
  48. data/lib/nilac/friendly_errors.rb +128 -0
  49. data/lib/nilac/get_variables.rb +48 -14
  50. data/lib/nilac/lexical_scoped_function_variables.rb +1 -3
  51. data/lib/nilac/optimizer.rb +13 -0
  52. data/lib/nilac/paranthesis_compactor.rb +3 -1
  53. data/lib/nilac/parse_arguments.rb +21 -7
  54. data/lib/nilac/pretty_print_javascript.rb +152 -18
  55. data/lib/nilac/pretty_print_nila.rb +17 -0
  56. data/lib/nilac/replace_comparison_operators.rb +25 -0
  57. data/lib/nilac/replace_multiline_comments.rb +4 -0
  58. data/lib/nilac/replace_singleline_comments.rb +23 -0
  59. data/lib/nilac/replace_strings.rb +3 -3
  60. data/lib/nilac/rollblocks.rb +7 -3
  61. data/lib/nilac/split_semicolon_seperated_expressions.rb +3 -17
  62. data/lib/nilac/square_brackets_compactor.rb +37 -0
  63. data/lib/nilac/version.rb +1 -1
  64. data/shark/features/arrays.feature +11 -0
  65. data/shark/features/builtin_new.feature +11 -0
  66. data/shark/features/comments.feature +11 -0
  67. data/shark/features/fix_newlines.feature +1 -1
  68. data/shark/features/variables.feature +11 -0
  69. data/shark/test_files/array_string_indexing.nila +5 -1
  70. data/shark/test_files/arrays.nila +3 -0
  71. data/shark/test_files/blocks.nila +10 -0
  72. data/shark/test_files/builtin_new.nila +3 -0
  73. data/shark/test_files/case.nila +8 -0
  74. data/shark/test_files/chained_comparison.nila +19 -0
  75. data/shark/test_files/comments.nila +15 -0
  76. data/shark/test_files/correct.js +1 -1
  77. data/shark/test_files/correct_arrays.js +7 -0
  78. data/shark/test_files/correct_blocks.js +14 -1
  79. data/shark/test_files/correct_builtin_new.js +9 -0
  80. data/shark/test_files/correct_case.js +10 -2
  81. data/shark/test_files/correct_comments.js +19 -0
  82. data/shark/test_files/correct_conditional_assignment.js +1 -1
  83. data/shark/test_files/correct_default_parameters.js +1 -1
  84. data/shark/test_files/correct_for.js +1 -1
  85. data/shark/test_files/correct_hashes.js +1 -1
  86. data/shark/test_files/correct_heredoc.js +6 -2
  87. data/shark/test_files/correct_if_then_else.js +5 -1
  88. data/shark/test_files/correct_indexing.js +7 -3
  89. data/shark/test_files/correct_initialization.js +1 -1
  90. data/shark/test_files/correct_javascript_methods.js +1 -1
  91. data/shark/test_files/correct_loop.js +1 -1
  92. data/shark/test_files/correct_monkey_patch.js +1 -1
  93. data/shark/test_files/correct_multiline_array.js +1 -1
  94. data/shark/test_files/correct_multiple_return.js +1 -1
  95. data/shark/test_files/correct_numbers.js +1 -1
  96. data/shark/test_files/correct_operators.js +1 -1
  97. data/shark/test_files/correct_regular_if.js +1 -1
  98. data/shark/test_files/correct_regular_while.js +1 -1
  99. data/shark/test_files/correct_required_module.js +1 -1
  100. data/shark/test_files/correct_return.js +1 -1
  101. data/shark/test_files/correct_ruby_methods.js +1 -1
  102. data/shark/test_files/correct_single_return.js +1 -1
  103. data/shark/test_files/{perfect.js → correct_spacing.js} +1 -1
  104. data/shark/test_files/correct_splats.js +1 -2
  105. data/shark/test_files/correct_string_interpolation.js +8 -2
  106. data/shark/test_files/correct_string_operators.js +1 -1
  107. data/shark/test_files/correct_times.js +1 -1
  108. data/shark/test_files/correct_unless_until.js +2 -4
  109. data/shark/test_files/correct_variables.js +13 -0
  110. data/shark/test_files/correct_whitespace_delimiter.js +1 -1
  111. data/shark/test_files/existential_operators.nila +7 -0
  112. data/shark/test_files/expression.nila +6 -0
  113. data/shark/test_files/global_variables_client.nila +5 -0
  114. data/shark/test_files/heredoc.nila +11 -1
  115. data/shark/test_files/if_then_else.nila +3 -1
  116. data/shark/test_files/inline_for.nila +5 -0
  117. data/shark/test_files/no_return.js +11 -0
  118. data/shark/test_files/parseInt_trap.nila +3 -0
  119. data/shark/test_files/single_return.js +11 -0
  120. data/shark/test_files/string_interpolation.nila +7 -1
  121. data/shark/test_files/variables.nila +7 -0
  122. metadata +54 -3
@@ -0,0 +1,79 @@
1
+ require_relative 'read_file_line_by_line'
2
+
3
+ def compose_nilac_options(input_options = {})
4
+
5
+ available_options = %w{bare strict-mode client server print}
6
+
7
+ output_options = {
8
+
9
+ :bare => false,
10
+
11
+ :strict_mode => false,
12
+
13
+ :client => false,
14
+
15
+ :server => true,
16
+
17
+ :print => false
18
+
19
+ }
20
+
21
+ options = input_options.clone.reject {|key,value| value.nil?}
22
+
23
+ options.each do |key,value|
24
+
25
+ current_options = options[key]
26
+
27
+ if current_options.include?("--bare") or current_options.include?("-b")
28
+
29
+ output_options[:bare] = true
30
+
31
+ input_options[key].delete("--bare")
32
+
33
+ input_options[key].delete("-b")
34
+
35
+ end
36
+
37
+ if current_options.include?("--strict-mode")
38
+
39
+ output_options[:strict_mode] = true
40
+
41
+ input_options[key].delete("--strict-mode")
42
+
43
+ end
44
+
45
+ if current_options.include?("--client") or current_options.include?("--browser")
46
+
47
+ output_options[:client] = true
48
+
49
+ input_options[key].delete("--client")
50
+
51
+ input_options[key].delete("--browser")
52
+
53
+ end
54
+
55
+ if current_options.include?("--server") or current_options.include?("--node")
56
+
57
+ output_options[:node] = true
58
+
59
+ input_options[key].delete("--server")
60
+
61
+ input_options[key].delete("--node")
62
+
63
+ end
64
+
65
+ if current_options.include?("--print") or current_options.include?("-p")
66
+
67
+ output_options[:print] = true
68
+
69
+ input_options[key].delete("--print")
70
+
71
+ input_options[key].delete("-p")
72
+
73
+ end
74
+
75
+ end
76
+
77
+ return output_options
78
+
79
+ end
@@ -14,7 +14,9 @@ require_relative 'paranthesis_compactor'
14
14
 
15
15
  if input_string.include?("=") and input_string.index(javascript_regexp) == nil and input_string.strip[0..3] != "_ref" and !input_string.split("=")[1].include?("[")
16
16
 
17
- right_side = input_string.split("=")[1]
17
+ right_side = input_string.split("=")[1] if input_string.count("=").eql?(1)
18
+
19
+ right_side = input_string.split("=",2)[1] if input_string.count("=") > 1
18
20
 
19
21
  if compact_paranthesis(right_side).include?(",")
20
22
 
@@ -0,0 +1,60 @@
1
+ def compile_ranges(input_file_contents)
2
+
3
+ # Currently, no implementation of Ranges exist for Nila. So we will be slowly developing one.
4
+ # In Ruby, Ranges are a separate entity and are not part of Arrays. Nila will take a similar approach to Ranges.
5
+
6
+ # In this section, we are introducing two Scala keywords to make range declaration more descriptive.
7
+ # The two new keywords are *to* and *until*
8
+
9
+ # Example:
10
+
11
+ # [1 to 5] is equivalent to [1..5]
12
+ # [1 until 5] is equivalent to [1...5]
13
+
14
+ triple_ranges = input_file_contents.reject {|element| !element.index(/(\d+\s*until\s*\d+|last)/)}
15
+
16
+ triple_ranges = triple_ranges.reject {|element| element.index(/(\d+\s*\.\.\.\s*\d+|last)/)}
17
+
18
+ triple_ranges.each do |line|
19
+
20
+ line_index = input_file_contents.index(line)
21
+
22
+ range_extracts = line.scan(/(\d+\s*until\s*\d+|last)/).to_a
23
+
24
+ range_extracts.each do |range|
25
+
26
+ begin_num,end_num = range[0].split("until").collect {|element| element.strip}
27
+
28
+ replacement_string = "#{begin_num}...#{end_num}"
29
+
30
+ input_file_contents[line_index] = input_file_contents[line_index].sub(range[0],replacement_string)
31
+
32
+ end
33
+
34
+ end
35
+
36
+ double_ranges = input_file_contents.reject {|element| !element.index(/(\d+\s*to\s*\d+|last)/)}
37
+
38
+ double_ranges = double_ranges.reject {|element| element.index(/(\d+\s*\.\.\s*\d+|last)/)}
39
+
40
+ double_ranges.each do |line|
41
+
42
+ line_index = input_file_contents.index(line)
43
+
44
+ range_extracts = line.scan(/(\d+\s*to\s*\d+|last)/).to_a
45
+
46
+ range_extracts.each do |range|
47
+
48
+ begin_num,end_num = range[0].split("to").collect {|element| element.strip}
49
+
50
+ replacement_string = "#{begin_num}..#{end_num}"
51
+
52
+ input_file_contents[line_index] = input_file_contents[line_index].sub(range[0],replacement_string)
53
+
54
+ end
55
+
56
+ end
57
+
58
+ return input_file_contents
59
+
60
+ end
@@ -12,9 +12,11 @@ def compile_require_statements(input_file_contents)
12
12
  #
13
13
  # var fs = require('fs')
14
14
 
15
- modified_file_contents = input_file_contents.collect {|element| replace_strings(element)}
15
+ modified_file_contents = input_file_contents.clone
16
16
 
17
- possible_require_calls = modified_file_contents.reject {|element| !element.include?("require")}
17
+ modified_file_contents = modified_file_contents.collect {|element| element.rstrip + " "*Random.new.rand(1..20) + "\n\n"}
18
+
19
+ possible_require_calls = modified_file_contents.reject {|element| !replace_strings(element).include?("require")}
18
20
 
19
21
  possible_require_calls.each do |statement|
20
22
 
@@ -0,0 +1,20 @@
1
+ def compile_ruby_math(input_file_contents)
2
+
3
+ # Ruby and Javascript both has powerful features. This library will be used to compile
4
+ # code written using the Ruby math library into Javascript Math library code
5
+
6
+ constant_value_map = {
7
+
8
+ "Math::E" => "Math.E"
9
+
10
+ }
11
+
12
+ constant_value_map.each do |key,value|
13
+
14
+ input_file_contents = input_file_contents.collect {|element| element.gsub(key,value)}
15
+
16
+ end
17
+
18
+ return input_file_contents
19
+
20
+ end
@@ -43,6 +43,44 @@
43
43
 
44
44
  end
45
45
 
46
+ def compile_simple_parameter_taking_methods(input_file_contents)
47
+
48
+ method_map_replacement = {
49
+
50
+ ".index" => ".indexOf"
51
+
52
+ }
53
+
54
+ method_map = method_map_replacement.keys
55
+
56
+ method_map_regex = method_map.collect {|name| name.gsub(".","\\.")}
57
+
58
+ method_map_regex = Regexp.new(method_map_regex.join("|"))
59
+
60
+ modified_file_contents = input_file_contents.clone
61
+
62
+ input_file_contents.each_with_index do |line, index|
63
+
64
+ if line.match(method_map_regex)
65
+
66
+ method_match = line.match(method_map_regex).to_a[0]
67
+
68
+ if line.include?(method_match + "(")
69
+
70
+ line = line.gsub(method_match,method_map_replacement[method_match])
71
+
72
+ end
73
+
74
+ end
75
+
76
+ modified_file_contents[index] = line
77
+
78
+ end
79
+
80
+ return modified_file_contents
81
+
82
+ end
83
+
46
84
  method_map_replacement = {
47
85
 
48
86
  ".split" => ".split(\" \")",
@@ -61,12 +99,21 @@
61
99
 
62
100
  ".empty" => ".length == 0",
63
101
 
102
+ ".notempty" => ".length != 0",
103
+
64
104
  ".upcase" => ".toUpperCase()",
65
105
 
66
106
  ".downcase" => ".toLowerCase()",
67
107
 
68
108
  ".zero?" => " === 0",
69
109
 
110
+ ".eql" => " === ",
111
+
112
+ ".next" => "++",
113
+
114
+ ".each" => ".forEach"
115
+
116
+
70
117
  }
71
118
 
72
119
  method_map = method_map_replacement.keys
@@ -97,6 +144,8 @@
97
144
 
98
145
  modified_file_contents = compile_complex_methods(modified_file_contents)
99
146
 
147
+ modified_file_contents = compile_simple_parameter_taking_methods(modified_file_contents)
148
+
100
149
  return modified_file_contents
101
150
 
102
151
  end
@@ -63,17 +63,31 @@ require_relative 'replace_strings'
63
63
 
64
64
  matching_strings = extract(joined_file_contents, function+" ", "\n")
65
65
 
66
+ matching_strings = matching_strings.reject {|element| !element.index(Regexp.new(function + /\s+=/.source)).nil?}
67
+
66
68
  matching_strings.each do |string|
67
69
 
68
70
  modified_string = string.dup
69
71
 
72
+ modified_string,comment = modified_string.split("--single_line_comment")
73
+
74
+ modified_string = modified_string + "\n" if modified_string != (modified_string + "\n")
75
+
70
76
  modified_string = modified_string.rstrip + modified_string.split(modified_string.rstrip)[1].gsub(" ", "")
71
77
 
72
78
  modified_string = modified_string.sub(function+" ", function+"(")
73
79
 
74
80
  modified_string = modified_string.split("#{function}(")[0] + "#{function}(" + modified_string.split("#{function}(")[1].lstrip
75
81
 
76
- modified_string = modified_string.sub("\n", ")\n")
82
+ if !comment.nil? and comment.strip != ""
83
+
84
+ modified_string = modified_string.sub("\n", ") --single_line_comment#{comment}\n")
85
+
86
+ else
87
+
88
+ modified_string = modified_string.sub("\n", ")\n")
89
+
90
+ end
77
91
 
78
92
  joined_file_contents = joined_file_contents.sub(string, modified_string)
79
93
 
@@ -0,0 +1,37 @@
1
+ def extract_paranthesis_contents(input_string)
2
+
3
+ string_extract = input_string.reverse
4
+
5
+ paranthesis_extract = [""]
6
+
7
+ two_paranthesis = ""
8
+
9
+ open_paran_index = nil
10
+
11
+ offset_value = nil
12
+
13
+ while string_extract.include?("(")
14
+
15
+ open_paran_index = string_extract.index("(")
16
+
17
+ test_extract = string_extract[0..open_paran_index].reverse
18
+
19
+ two_paranthesis = test_extract[0..test_extract.index(")")]
20
+
21
+ previous_value = paranthesis_extract[-1]
22
+
23
+ if previous_value.length > two_paranthesis.length-(two_paranthesis.count("$@"))/2
24
+
25
+ offset_value = previous_value
26
+
27
+ end
28
+
29
+ paranthesis_extract << two_paranthesis.sub("$@"*previous_value.length,previous_value)
30
+
31
+ string_extract = string_extract.sub(two_paranthesis.reverse,"@$"*paranthesis_extract[-1].length)
32
+
33
+ end
34
+
35
+ return paranthesis_extract
36
+
37
+ end
@@ -0,0 +1,63 @@
1
+ # This is a simple method to extract user written strings
2
+
3
+ def extract_strings(input_string)
4
+
5
+ element = input_string.gsub("==", "equalequal")
6
+
7
+ element = element.gsub("!=", "notequal")
8
+
9
+ element = element.gsub("+=", "plusequal")
10
+
11
+ element = element.gsub("-=", "minusequal")
12
+
13
+ element = element.gsub("*=", "multiequal")
14
+
15
+ element = element.gsub("/=", "divequal")
16
+
17
+ element = element.gsub("%=", "modequal")
18
+
19
+ element = element.gsub("=~", "matchequal")
20
+
21
+ element = element.gsub(">=", "greatequal")
22
+
23
+ input_string = element.gsub("<=", "lessyequal")
24
+
25
+ string_counter = 0
26
+
27
+ string_array = []
28
+
29
+ if input_string.count("\"") % 2 == 0
30
+
31
+ while input_string.include?("\"")
32
+
33
+ string_extract = input_string[input_string.index("\"")..input_string.index("\"",input_string.index("\"")+1)]
34
+
35
+ string_array << string_extract
36
+
37
+ input_string = input_string.sub(string_extract,"--repstring#{string_counter}")
38
+
39
+ string_counter += 1
40
+
41
+ end
42
+
43
+ end
44
+
45
+ if input_string.count("'") % 2 == 0
46
+
47
+ while input_string.include?("'")
48
+
49
+ string_extract = input_string[input_string.index("'")..input_string.index("'",input_string.index("'")+1)]
50
+
51
+ input_string = input_string.sub(string_extract,"--repstring#{string_counter}")
52
+
53
+ string_array << string_extract
54
+
55
+ string_counter += 1
56
+
57
+ end
58
+
59
+ end
60
+
61
+ return string_array
62
+
63
+ end
@@ -0,0 +1,89 @@
1
+ require_relative 'replace_strings'
2
+ require_relative 'extract_paranthesis_contents'
3
+
4
+ def fix_javascript_traps(input_file_contents)
5
+
6
+ # One of the design goals of Nila is to fix to Javascript traps
7
+
8
+ # parseInt is a potential trap if you forget the radix parameter. So
9
+ # Nila automatically includes the radix parameter of 10 if you forget to include a parameter
10
+ # so that you don't get weird conversions like the one mentioned in
11
+ # http://stackoverflow.com/questions/850341/how-do-i-work-around-javascripts-parseint-octal-behavior
12
+
13
+ def fix_parseint_default(input_file_contents)
14
+
15
+ possible_parseints = input_file_contents.reject {|element| !replace_strings(element).include?("parseInt")}
16
+
17
+ no_radix = []
18
+
19
+ no_radix_lines = []
20
+
21
+ possible_parseints.each do |str|
22
+
23
+ index = input_file_contents.index(str)
24
+
25
+ no_radix << []
26
+
27
+ no_radix_lines << []
28
+
29
+ paran_extracts = extract_paranthesis_contents(str)
30
+
31
+ paran_extracts = paran_extracts.reject {|element| element.strip.eql?("")}
32
+
33
+ paran_extracts.each do |extract|
34
+
35
+ if input_file_contents[index].include?("parseInt#{extract}")
36
+
37
+ extracted_parseint = "parseInt#{extract}"
38
+
39
+ extract_split = replace_strings(extract).split(",")
40
+
41
+ if extract_split.length == 1
42
+
43
+ no_radix[-1] << extracted_parseint
44
+
45
+ no_radix_lines[-1] << input_file_contents[index]
46
+
47
+ end
48
+
49
+ end
50
+
51
+ end
52
+
53
+ end
54
+
55
+ no_radix_lines = no_radix_lines.collect{|element| element.uniq}
56
+
57
+ no_radix_lines = no_radix_lines.reject {|element| element.empty?}
58
+
59
+ no_radix = no_radix.reject {|element| element.empty?}
60
+
61
+ no_radix_lines.each_with_index do |element,index|
62
+
63
+ extracted_parseints = no_radix[index]
64
+
65
+ modified_element = element[0].clone
66
+
67
+ extracted_parseints.each do |parseint|
68
+
69
+ replacement_string = parseint[0...-1] + ",10" + parseint[-1]
70
+
71
+ modified_element = modified_element.sub(parseint,replacement_string)
72
+
73
+ end
74
+
75
+ input_file_contents[input_file_contents.index(element[0])] = modified_element
76
+
77
+ end
78
+
79
+ return input_file_contents
80
+
81
+ end
82
+
83
+ input_file_contents = fix_parseint_default(input_file_contents)
84
+
85
+
86
+ return input_file_contents
87
+
88
+
89
+ end