alphalang 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
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