alphalang 0.1.2 → 0.1.3

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bb11af78d1a68ee1f2a5aaba719040996f435be0183e690bea2532a7fce80201
4
- data.tar.gz: 0f5a33e46b3fa611bab83528e90c481e5ba4ec1a480808a1bc7551fc25b90e4e
3
+ metadata.gz: 1c31a662b58f22db4c35e2e784739c0c0def7b9ccef89ad3f06292581dfdf28d
4
+ data.tar.gz: bc02c5bfcdac5985367a5c722b88b01a4d95d35c973dcb6e61d1a05c66de23e2
5
5
  SHA512:
6
- metadata.gz: 7411738e5cd015019a137324144b4a735f3e195263cc23ddf1301ecc2a3803be9ede4d28cc4f84403cb6547bc8dc6c75cf9ee59e307ef22d692632daa1439b58
7
- data.tar.gz: b9ebbb5a83f4a2fb5f547754e7458e0de1249ff0e15fa79a293c5d56727d68237b6ff2de9d9b9be08866440dd5195f1eeff777b11eda23606a05c6b62941c54f
6
+ metadata.gz: 7c104ae659e875f33f9b3d9ac8f358613feab8dfe56b2b166b580626994a9089c8e6ecdb307cee7b8d64e80ba0e1b63f7be7380360cf427bc18e0eb34469d966
7
+ data.tar.gz: 30f09cb6a7a6c914b0be2d84a50cd88495e482fdec29c06c49fc8d2d9bd306795a86cf26d08065b6d0da8b0b0a8458fa06cc664694c72fe546abd6f1e3adbb41
data/bin/alphalang CHANGED
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
2
  require 'optparse'
3
3
  require File.expand_path('../lib/alpha', __dir__)
4
- ALPHA_VER = '0.1.2'.freeze
4
+ ALPHA_VER = '0.1.3'.freeze
5
+ ABORT_ANSWERS = [' ', '', 'none', 'abort'].freeze # something here? Some cases empty means yes tho..
5
6
 
6
7
  basic_error_msg = "Usage: alphalang [options] file.alpha\nUsage: alphalang -h for the help menu."
7
8
 
@@ -21,22 +22,55 @@ OptionParser.new do |opts|
21
22
  options[:lang] = lang
22
23
  end
23
24
 
24
- opts.on('--createlocale', 'Creates a new locale-file for all program keywords available.') do
25
+ opts.on('--createlocale', 'Creates a new locale file for all program keywords available.') do
25
26
  options[:createlocale] = true
26
27
  end
28
+
29
+ opts.on('--deletelocale', 'Deletes a locale file from your locales directory.') do
30
+ options[:deletelocale] = true
31
+ end
32
+
33
+ opts.on('--listlocales', 'Lists all available locale files from your locales directory.') do
34
+ options[:listlocales] = true
35
+ end
36
+
37
+ opts.on('--listlocale', 'Lists all keywords from a specific locale file from your locales directory.') do
38
+ options[:listlocale] = true
39
+ end
27
40
  end.parse!
28
41
 
29
42
  verbose = options[:verbose]
30
43
  verify = options[:verify]
31
44
  language = options[:lang] || 'en'
32
- createlocale = options[:createlocale]
45
+ create_locale_flag = options[:createlocale]
46
+ delete_locale_flag = options[:deletelocale]
47
+ list_locales_flag = options[:listlocales]
48
+ list_locale_flag = options[:listlocale]
33
49
 
34
- if createlocale
50
+ if create_locale_flag
35
51
  require_relative '../lib/lang_creator'
36
52
  create_locale_file
37
53
  return
38
54
  end
39
55
 
56
+ if delete_locale_flag
57
+ require_relative '../lib/locale_deleter'
58
+ delete_locale_file
59
+ return
60
+ end
61
+
62
+ if list_locales_flag
63
+ require_relative '../lib/locale_lister'
64
+ list_locale_files
65
+ return
66
+ end
67
+
68
+ if list_locale_flag
69
+ require_relative '../lib/locale_lister'
70
+ list_specific_locale_file
71
+ return
72
+ end
73
+
40
74
  raise OptionParser::MissingArgument, "No file provided.
41
75
  Usage: alphalang my_file.alpha | alphalang -h" if ARGV.empty? unless verify
42
76
  raise OptionParser::InvalidArgument, 'Too many files provided.
@@ -50,7 +84,7 @@ else
50
84
  end
51
85
 
52
86
  if verify
53
- if !ARGV.empty?
87
+ unless ARGV.empty?
54
88
  puts 'Flag for verification found. Ignoring input file.'
55
89
  sleep 1
56
90
  end
data/lib/alpha.rb CHANGED
@@ -1,7 +1,8 @@
1
1
  require_relative './nodes/stmtnodes'
2
2
 
3
3
  class LangParser
4
- def initialize(locale='en')
4
+ def initialize(locale = 'en')
5
+ ScopeManager.new
5
6
  @langParser = Parser.new('lang parser', locale) do
6
7
  token(/while/) { |_| :WHILE }
7
8
  token(/print/) { |_| :PRINT }
@@ -81,11 +82,6 @@ class LangParser
81
82
  match(:member, '=', :array_stmt) { |var, _, value| VariableDecNode.new(var, value) }
82
83
  end
83
84
 
84
- #array inte klar kan assigna till vaiabel men inte kolla upp än
85
- rule :array_stmt do
86
- match('[', :arg_list, ']') { |_, array, _| array }
87
- end
88
-
89
85
  rule :pause_stmt do
90
86
  match(:PAUSE, :expr) { |_, a| PauseNode.new(a) }
91
87
  end
@@ -109,6 +105,15 @@ class LangParser
109
105
  match(:NOT, :expr_stmt) { |_, b| NotNode.new(b) }
110
106
  end
111
107
 
108
+ rule :array_stmt do
109
+ match('[', :arg_list, ']') { |_, array, _| array }
110
+ end
111
+
112
+ rule :arg_list do
113
+ match(:expr, ',', :arg_list) { |a, _, b| ArrayNode.new(a, b) }
114
+ match(:expr) { |a| ArrayNode.new(a, NilClass) }
115
+ end
116
+
112
117
  rule :expr do
113
118
  match(:expr, /(<|>)/, :expr) { |a, op, b| CompareNode.new(a, op, b) }
114
119
  match(/(<|>)/, :expr) { |op, b| CompareNode.new(nil, op, b) }
@@ -141,14 +146,11 @@ class LangParser
141
146
  rule :member do
142
147
  match(/[a-z]/, '(', :arg_list, ')') { |var, _, args, _| FuncCallNode.new(var, args) }
143
148
  match(/[a-z]/, '(', ')') { |var, _, _| FuncCallNode.new(var, NilClass) }
149
+ match(/[a-z]/, '[', '-', /\d+/, ']') { |var, _, neg, index, _| ArrayCallNode.new(var, (neg+index)) }
150
+ match(/[a-z]/, '[', /\d+/, ']') { |var, _, index, _| ArrayCallNode.new(var, index) }
144
151
  match(/[a-z]/) { |var| VariableCallNode.new(var) }
145
152
  end
146
153
 
147
- rule :arg_list do
148
- match(:expr, ',', :arg_list) { |a, _, b| ArrayNode.new(a, b) }
149
- match(:expr) { |a| ArrayNode.new(a, NilClass) }
150
- end
151
-
152
154
  rule :prio_stmt do
153
155
  match('(', :stmt, ')') { |_, a, _| a }
154
156
  end
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ def prompt_user_for_deletion(locales, install_path, protected_paths)
4
+ puts 'Which locale would you like to delete?: RET or "none" to abort'
5
+
6
+ locales.each do |locale|
7
+ puts locale
8
+ end
9
+
10
+ locale_file = gets.chomp
11
+
12
+ return if ABORT_ANSWERS.include?(locale_file)
13
+
14
+ if protected_paths.include?(locale_file)
15
+ puts 'You may not delete a default locale.'
16
+ return
17
+ else
18
+ File.delete("#{install_path}/#{locale_file}")
19
+ puts "Successfully deleted #{install_path}/#{locale_file}"
20
+ end
21
+ end
22
+
23
+ def delete_locale_file()
24
+ locale_path = File.join(__dir__, 'locales')
25
+ protected_locales = ['.', '..', 'locale_template', 'en', 'sv', 'de']
26
+
27
+ imported_locales = Dir.entries(locale_path).reject { |entry| protected_locales.include?(entry) }
28
+
29
+ if imported_locales.empty?
30
+ puts '[alphalang] There are no locale files to delete. Default locale files are protected.'
31
+ return
32
+ else
33
+ prompt_user_for_deletion(imported_locales, locale_path, protected_locales)
34
+ end
35
+ end
File without changes
@@ -0,0 +1,50 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # extra_entries_array in case we wanna make a "protected locale" function later on
4
+ def get_locale_files(extra_entries_array = [])
5
+ locale_path = File.join(__dir__, 'locales')
6
+ protected_locales = ['.', '..', 'locale_template', extra_entries_array].flatten
7
+ Dir.entries(locale_path).reject { |entry| protected_locales.include?(entry) }
8
+ end
9
+
10
+ def list_locale_files()
11
+ locales = get_locale_files
12
+ puts '[alphalang] These are the available locales.'
13
+ locales.each do |locale|
14
+ puts locale
15
+ end
16
+ puts
17
+ end
18
+
19
+ def list_specific_locale_file()
20
+ list_locale_files
21
+ specific_locale = gets.chomp
22
+
23
+ return if ABORT_ANSWERS.include?(specific_locale)
24
+
25
+ locale_path = File.join(__dir__, 'locales')
26
+ locale_file = File.readlines("#{locale_path}/#{specific_locale}")
27
+
28
+ clean_locale_file_array = []
29
+ locale_file.each do |line|
30
+ line.scan(/\b\p{L}+\b/) do |word|
31
+ clean_locale_file_array << word if word.size > 1
32
+ end
33
+ end
34
+
35
+ header = "\n[alphalang] Syntax for locale <#{specific_locale}>."
36
+ puts header
37
+ puts '+' * (header.size - 2)
38
+ clean_line = ''
39
+ clean_locale_file_array.each_with_index do |word, index|
40
+ if index.even?
41
+ clean_line += "+ #{word}"
42
+ else
43
+ clean_line += (' ' * (20 - clean_line.size)) + "#{word}"
44
+ clean_line += (' ' * (header.size - clean_line.size - 3) + '+')
45
+ puts clean_line
46
+ clean_line = ''
47
+ end
48
+ end
49
+ puts '+' * (header.size - 2)
50
+ end
File without changes
@@ -1,9 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
- ####################################################
3
-
4
- $scopes = [{}]
5
- $scope_lvl = 0
6
- $test_nodes = false
7
2
 
8
3
  ####################################################
9
4
 
@@ -1,26 +1,65 @@
1
1
  require_relative 'basenodes'
2
2
 
3
3
  ####################################################
4
- class VariableCallNode < Node
5
- attr_accessor :name
6
4
 
7
- def initialize(name)
8
- @name = name
5
+ $scopes = [{}]
6
+ $scope_lvl = 0
7
+ $test_nodes = false
8
+
9
+ # Need to expand this to actually handle scopes, not just lookups
10
+ class ScopeManager
11
+ def self.scope_lvl
12
+ $scope_lvl
9
13
  end
10
14
 
11
- def lookup_var(name)
15
+ def self.lookup_var(name)
12
16
  temp_scope_lvl = $scope_lvl
13
17
  while temp_scope_lvl >= 0
14
- if not $scopes[temp_scope_lvl].has_key?(name)
18
+ if !$scopes[temp_scope_lvl].key?(name)
15
19
  temp_scope_lvl -= 1
16
20
  else
17
21
  return $scopes[temp_scope_lvl][name]
18
22
  end
19
23
  end
24
+ raise ArgumentError, "Variable '#{name}' is not defined" unless @value
25
+ end
26
+
27
+ def self.increment_scope_level
28
+ $scope_lvl += 1
29
+ $scopes.push({})
30
+ end
31
+
32
+ def self.decrement_scope_level
33
+ $scope_lvl -= 1
34
+ $scopes.pop
35
+ end
36
+
37
+ def self.lookup_func(name)
38
+ raise ArgumentError, "Function '#{name}' is not defined" if $scopes[0][name].is_a?(NilClass)
39
+ return $scopes[0][name]
40
+ end
41
+
42
+ def self.add_to_current_scope(name, value)
43
+ $scopes[$scope_lvl][name.name] = value.evaluate
44
+ end
45
+
46
+ def self.add_func_to_global_scope(name, value, args)
47
+ $scopes[0][name.name] = [value, args]
48
+ end
49
+ end
50
+
51
+ ####################################################
52
+
53
+ class VariableCallNode < Node
54
+ attr_accessor :name
55
+
56
+ def initialize(name)
57
+ @name = name
20
58
  end
21
59
 
22
60
  def evaluate
23
- return @value = lookup_var(@name)
61
+ @value = ScopeManager.lookup_var(@name)
62
+ return @value
24
63
  end
25
64
  end
26
65
 
@@ -33,9 +72,8 @@ class VariableDecNode < Node
33
72
  end
34
73
 
35
74
  def evaluate
36
- $scopes[$scope_lvl][@name.name] = @value.evaluate
75
+ ScopeManager.add_to_current_scope(name, @value)
37
76
  self
38
- # return nil
39
77
  end
40
78
  end
41
79
 
@@ -49,7 +87,7 @@ class FunctionDecNode < Node
49
87
  end
50
88
 
51
89
  def evaluate
52
- $scopes[0][@name.name] = [@value, @args]
90
+ ScopeManager.add_func_to_global_scope(@name, @value, @args)
53
91
  return nil
54
92
  end
55
93
  end
@@ -62,19 +100,13 @@ class FuncCallNode < Node
62
100
  @args = args
63
101
  end
64
102
 
65
- def lookup_var(name)
66
- return $scopes[0][name]
67
- end
68
-
69
103
  def evaluate
70
- $scopes.push({})
71
- func = lookup_var(@name)
104
+ func = ScopeManager.lookup_func(@name)
105
+
72
106
  function_body = func[0]
73
107
  function_param = func[1]
74
108
 
75
- return nil if func.is_a?(NilClass)
76
-
77
- $scope_lvl += 1
109
+ ScopeManager.increment_scope_level
78
110
 
79
111
  if function_param.is_a?(ArrayNode)
80
112
  function_param.each do |val, index|
@@ -83,18 +115,18 @@ class FuncCallNode < Node
83
115
  end
84
116
  end
85
117
 
86
- func_result = function_body.evaluate
87
- old_scope_lvl = $scope_lvl
88
- # Om en assign är returnvärde så declareras variablen i globalt scope
89
- if func_result.is_a?(VariableDecNode)
90
- $scope_lvl = 0
91
- func_result.evaluate
92
- $scope_lvl = old_scope_lvl
93
- end
118
+ func_return_value = function_body.evaluate
94
119
 
95
- $scope_lvl -= 1
96
- $scopes.pop
97
- return func_result
120
+ ScopeManager.decrement_scope_level
121
+
122
+ # If function return value is an "Assign" then we declare that variable in the global scope.
123
+ old_scope_lvl = ScopeManager.scope_lvl
124
+ if func_return_value.is_a?(VariableDecNode)
125
+ ScopeManager.scope_lvl = 0
126
+ func_return_value.evaluate
127
+ ScopeManager.scope_lvl = old_scope_lvl
128
+ end
129
+ return func_return_value
98
130
  end
99
131
  end
100
132
 
@@ -176,6 +208,23 @@ end
176
208
 
177
209
  ####################################################
178
210
 
211
+ class ArrayCallNode < Node
212
+ def initialize(array, index)
213
+ super(array)
214
+ @index = index.to_i
215
+ end
216
+
217
+ def evaluate
218
+ arr = ScopeManager.lookup_var(@value)
219
+ if @index > arr.size - 1
220
+ raise ArgumentError, "You are trying to access an out of bounds index. Here -> #{@value}[#{@index}]"
221
+ end
222
+ @value = arr[@index]
223
+ end
224
+ end
225
+
226
+ ####################################################
227
+
179
228
  class PrintNode
180
229
  attr_accessor :value
181
230
 
@@ -185,7 +234,7 @@ class PrintNode
185
234
 
186
235
  def evaluate
187
236
  puts @value.evaluate
188
- self.class # detta kanske är trevligare än nil, åter igen den diskussionen.
237
+ self.class
189
238
  end
190
239
  end
191
240
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: alphalang
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - mattias
@@ -61,6 +61,10 @@ files:
61
61
  - bin/alphalang
62
62
  - lib/alpha.rb
63
63
  - lib/lang_creator.rb
64
+ - lib/locale_deleter.rb
65
+ - lib/locale_deleter.rb~
66
+ - lib/locale_lister.rb
67
+ - lib/locale_lister.rb~
64
68
  - lib/locales/de
65
69
  - lib/locales/en
66
70
  - lib/locales/locale_template