alphalang 0.2.9 → 0.3.0

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: fd90e0cc81ecac899602c5a173f188110fecd877428fcab72e8bc77076e75d00
4
- data.tar.gz: 1b1e538edb038c95ccffcb50fb8f48f5081977701082164da879ab848af80edb
3
+ metadata.gz: c79a0fb156d98b42640f99526fcf8b6274828c07f8504b9d4b3563fdedb9078d
4
+ data.tar.gz: 9b0c5a2476e297ba4b78165608e43adb96cf4312e99f8530a1a6cb4d8d466a09
5
5
  SHA512:
6
- metadata.gz: 95e31bbc359dc485d7e5e623164f2f3c636c68975e6c7bd1c83fcfe75c11cbe8b1fe6c4d35eeefae0bfcf7c0b668f673a8649cea39d9bfe6f7319d860947e87b
7
- data.tar.gz: 15cd10c8ce16fea278f3d99f3c8caecf3e811249c6a1d933360433d22ca06c0816602555a1aa314ba720a00229e6401256520de7d664da884a98e1bff2e3d24e
6
+ metadata.gz: df72d6c52254c86ad8cd85000bf5e44a614d2909d1e55b1620cba8fdb2ba9a8b3552b27b8b034e4f5147752a21e51686c3613b36b237b2ced95fc4fcffafedc2
7
+ data.tar.gz: d8bc966079ac40acf1af38adf08654fd8b7961f4b79067d747d94b23f6e99cff5f7a0ee75a6829de8eb34679284b623fb6891e7f893d1eb8c655ecb7dac8ae84
data/bin/alphalang CHANGED
@@ -45,7 +45,7 @@ OptionParser.new do |opts|
45
45
  options[:listlocale] = true
46
46
  end
47
47
 
48
- opts.on('--printtree', 'Lists all keywords from a specific locale file from your locales directory.') do
48
+ opts.on('-p', '--printtree', 'Prints the abstract syntax tree in a simple form.') do
49
49
  options[:printtree] = true
50
50
  end
51
51
  end.parse!
@@ -61,6 +61,8 @@ list_locale_flag = options[:listlocale]
61
61
  PRINT_TREE_FLAG = options[:printtree]
62
62
  TREE_ARRAY = []
63
63
 
64
+ raise Errno::EBADR, "Don't use --logger and --printtree together." if PRINT_TREE_FLAG and verbose_flag
65
+
64
66
  if create_locale_flag
65
67
  require_relative '../lib/locale_creator'
66
68
  create_locale_file
data/lib/alpha.rb CHANGED
@@ -24,11 +24,6 @@ class LangParser
24
24
 
25
25
  start :program do
26
26
  match(:comp_stmt)
27
- match(:terminal)
28
- end
29
-
30
- rule :terminal do
31
- match(/\n|;/)
32
27
  end
33
28
 
34
29
  rule :comp_stmt do
@@ -64,12 +59,12 @@ class LangParser
64
59
 
65
60
  rule :if_comp_stmt do
66
61
  match(:if_stmt, :comp_elseif, :else_stmt, :STOP) { |a, b, c| IfCompStmtNode.new(a, b, c) }
62
+ match(:if_stmt, :comp_elseif, :STOP) { |a, b| IfCompStmtNode.new(a, b) }
67
63
  match(:if_stmt, :else_stmt, :STOP) { |a, b| IfCompStmtNode.new(a, b) }
68
64
  match(:if_stmt, :STOP) { |a| IfCompStmtNode.new(a) }
69
65
  end
70
66
 
71
67
  rule :if_stmt do
72
- match(:IF, :expr_stmt, :and, :expr_stmt, :comp_stmt) { |_, a, b, c, d| IfCompactNode.new(a, b, c, d) }
73
68
  match(:IF, :expr_stmt, :comp_stmt) { |_, a, b| IfNode.new(a, b) }
74
69
  end
75
70
 
@@ -165,15 +160,11 @@ class LangParser
165
160
  rule :atom do
166
161
  match(:number)
167
162
  match(:boolean)
163
+ match(:string)
168
164
  match(:call_member)
169
165
  match(:prio_stmt)
170
166
  end
171
167
 
172
- rule :boolean do
173
- match(ScopeManager.true_value) { |a| BoolNode.new(a) }
174
- match(ScopeManager.false_value) { |a| BoolNode.new(a) }
175
- end
176
-
177
168
  rule :number do
178
169
  match('-', /\d+/, '.', /\d+/) { |neg, a, dot, b| NumberNode.new(neg + a + dot + b) }
179
170
  match(/\d+/, '.', /\d+/) { |a, dot, b| NumberNode.new(a + dot + b) }
@@ -181,6 +172,25 @@ class LangParser
181
172
  match(/\d+/) { |a| NumberNode.new(a) }
182
173
  end
183
174
 
175
+ rule :boolean do
176
+ match(ScopeManager.true_value) { |a| BoolNode.new(a) }
177
+ match(ScopeManager.false_value) { |a| BoolNode.new(a) }
178
+ end
179
+
180
+ rule :string do
181
+ match('"', :comp_string, '"') { |_, str, _| StringNode.new(str) }
182
+ end
183
+
184
+ # TODO: Figure out if this is possible with char without messing too much with lexer
185
+ rule :comp_string do
186
+ match(:word, :comp_string) { |a, b| [a, b].flatten }
187
+ match(:word)
188
+ end
189
+
190
+ rule :word do
191
+ match(/\w/) { |m| m }
192
+ end
193
+
184
194
  rule :call_member do
185
195
  match(:member, '(', :arg_list, ')') { |var, _, args, _| FuncCallNode.new(var, args) }
186
196
  match(:member, '(', ')') { |var, _, _| FuncCallNode.new(var, NilClass) }
@@ -0,0 +1,68 @@
1
+ # Error Handler, imported by RDParse.
2
+ class ErrorHandler
3
+ class ParseError < RuntimeError
4
+ end
5
+
6
+ def self.convert_regex_sensitive_token(token, token_list)
7
+ token = token_list['end'] if token == :STOP
8
+ token = "#{token_list['(not|!)'].split('|')[0][1..]}" if token == :NOT
9
+ token = "#{token_list['(and|&&)'].split('|')[0][1..]}" if token == :AND
10
+ token = "#{token_list['(or|\|\|)'].split('|')[0][1..]}" if token == :OR
11
+ token = '[(]' if token == '('
12
+ token = '[)]' if token == ')'
13
+ token = '[+]' if token == '+'
14
+ token = '[-]' if token == '-'
15
+ token = '[*]' if token == '*'
16
+ token = '[/]' if token == '/'
17
+ token
18
+ end
19
+
20
+ def self.translate_tokens_array(array, token_list)
21
+ result = []
22
+ array.each do |token|
23
+ token = convert_regex_sensitive_token(token, token_list)
24
+ result << token unless token.is_a?(Symbol)
25
+ result << token_list[token.to_s.downcase] if token.is_a?(Symbol)
26
+ end
27
+ result
28
+ end
29
+
30
+ def self.find_surrounding_code(problem_pos, tokens)
31
+ tokens_before_problem = []
32
+ temp = problem_pos
33
+ while temp >= 0
34
+ tokens_before_problem << tokens[temp]
35
+ temp -= 1
36
+ end
37
+ tokens_before_problem.reverse
38
+ end
39
+
40
+ def self.find_faulty_line(pos, file_string, tokens, token_list)
41
+ tokens_before_problem = find_surrounding_code(pos - 1, tokens)
42
+ file_as_array_without_whitespaces = translate_tokens_array(tokens_before_problem, token_list)
43
+
44
+ pattern = file_as_array_without_whitespaces.join('\s*')
45
+ regex = Regexp.new(pattern)
46
+
47
+ # Remove comments, replace entire comment lines with "\n" to perserve num_lines
48
+ cleaned_string = file_string.gsub(/^;;.*/, "\n")
49
+ cleaned_string = cleaned_string.gsub(/;;.*/, '')
50
+
51
+ match_data = regex.match(cleaned_string)
52
+ num_lines = match_data[0].count("\n") + 1 unless NilClass # TODO: Find out what causes these edge cases
53
+
54
+ problem = tokens[pos]
55
+ line_msg = "There is a problem on line #{num_lines}"
56
+ line_msg = "Couldn't precise the exact line" if num_lines.is_a?(NilClass) # TODO: Find out edge cases
57
+
58
+ if tokens_before_problem[-1] == :PRINT
59
+ raise ParseError, "#{line_msg} with the <#{token_list['print']}> statement, needs something to print."
60
+ elsif tokens_before_problem[-1] == :PAUSE
61
+ raise ParseError, "#{line_msg} with the <#{token_list['pause']}> statement, pause needs a numeric argument."
62
+ elsif problem == :STOP
63
+ raise ParseError, "#{line_msg}. Found <#{token_list['end']}>\nEmpty if-statements and functions are not allowed"
64
+ else
65
+ raise ParseError, "#{line_msg}. Found <#{problem}>"
66
+ end
67
+ end
68
+ end
File without changes
@@ -45,16 +45,57 @@ class BoolNode < Node
45
45
  end
46
46
  end
47
47
 
48
+ # See ArrayNode for a more complete Data Structure
49
+ class StringNode < Node
50
+ def initialize(value)
51
+ if value.is_a?(String)
52
+ super
53
+ else
54
+ super(value.join(' '))
55
+ end
56
+ end
57
+
58
+ def +(other)
59
+ raise NotImplementedError, 'Addition is not implemented for Strings.'
60
+ end
61
+
62
+ def -(other)
63
+ raise NotImplementedError, 'Subtraction is not implemented for Strings.'
64
+ end
65
+
66
+ def *(other)
67
+ raise NotImplementedError, 'Multiplication is not implemented for Strings.'
68
+ end
69
+
70
+ def /(other)
71
+ raise NotImplementedError, 'Division is not implemented for Strings.'
72
+ end
73
+
74
+ def to_i
75
+ @value.to_i
76
+ end
77
+
78
+ def to_f
79
+ @value.to_f
80
+ end
81
+
82
+ def contains?(other)
83
+ return if @value.include?(other)
84
+ end
85
+
86
+ def evaluate
87
+ self
88
+ end
89
+ end
90
+
48
91
  ###################### Logic Gate Nodes
49
92
 
50
93
  class AndNode < Node
51
94
  def initialize(lhs, rhs)
52
95
  @lhs, @rhs = lhs, rhs
53
- if @rhs.class.method_defined? (:lhs)
54
- if @rhs.lhs == nil
55
- @rhs.lhs = @lhs.lhs
56
- end
57
- end
96
+ return unless @rhs.class.method_defined?(:lhs)
97
+
98
+ @rhs.lhs = @lhs.lhs if @rhs.lhs == nil
58
99
  end
59
100
 
60
101
  def to_s
@@ -69,11 +110,9 @@ end
69
110
  class OrNode < Node
70
111
  def initialize(lhs, rhs)
71
112
  @lhs, @rhs = lhs, rhs
72
- if @rhs.class.method_defined? (:lhs)
73
- if @rhs.lhs == nil
74
- @rhs.lhs = @lhs.lhs
75
- end
76
- end
113
+ return unless @rhs.class.method_defined?(:lhs)
114
+
115
+ @rhs.lhs = @lhs.lhs if @rhs.lhs == nil
77
116
  end
78
117
 
79
118
  def to_s
@@ -306,6 +306,9 @@ class PauseNode < Node
306
306
  end
307
307
 
308
308
  def evaluate
309
+ # TODO: Create an Error Handler class... Needs to use rdparses functions here for a more helpful msg.
310
+ raise SyntaxError, 'Pause needs a numeric argument.' unless @value.evaluate.is_a?(Numeric)
311
+
309
312
  @value = 0 if @value.evaluate.negative?
310
313
  create_tree_entry if PRINT_TREE_FLAG
311
314
  sleep @value.evaluate
data/lib/rdparse.rb CHANGED
@@ -8,6 +8,7 @@
8
8
  # 2014-02-16 New version that handles { false } blocks and :empty tokens.
9
9
 
10
10
  require 'logger'
11
+ require_relative 'error_handler'
11
12
 
12
13
  class Rule
13
14
 
@@ -187,58 +188,6 @@ class Parser
187
188
  end # until
188
189
  end
189
190
 
190
- def convert_regex_sensitive_token(token)
191
- token = @token_list['end'] if token == :STOP # fulhack pga :END påstods inte funka för länge sen
192
- token = '[(]' if token == '('
193
- token = '[)]' if token == ')'
194
- token = '[+]' if token == '+'
195
- token = '[-]' if token == '-'
196
- token = '[*]' if token == '*'
197
- token = '[/]' if token == '/'
198
- token = "#{@token_list['(not|!)'].split('|')[0][1..]}" if token == :NOT
199
- token = "#{@token_list['(and|&&)'].split('|')[0][1..]}" if token == :AND
200
- token = "#{@token_list['(or|\|\|)'].split('|')[0][1..]}" if token == :OR
201
- token
202
- end
203
-
204
- def translate_tokens_array(array)
205
- result = []
206
- array.each do |token|
207
- token = convert_regex_sensitive_token(token)
208
- result << token unless token.is_a?(Symbol)
209
- result << @token_list[token.to_s.downcase] if token.is_a?(Symbol)
210
- end
211
- result
212
- end
213
-
214
- def find_surrounding_code(problem_pos)
215
- tokens_before_problem = []
216
- temp = problem_pos
217
- while temp >= 0
218
- tokens_before_problem << @tokens[temp]
219
- temp -= 1
220
- end
221
- tokens_before_problem.reverse
222
- end
223
-
224
- def find_faulty_line
225
- tokens_before_problem = find_surrounding_code(@max_pos - 1)
226
- file_as_array_without_whitespaces = translate_tokens_array(tokens_before_problem)
227
-
228
- pattern = file_as_array_without_whitespaces.join('\s*')
229
- regex = Regexp.new(pattern)
230
-
231
- cleaned_string = @file_string.gsub(/;;.*/, '')
232
-
233
- match_data = regex.match(cleaned_string)
234
- num_lines = match_data[0].count("\n") + 1
235
-
236
- problem = @tokens[@max_pos]
237
- problem = @token_list[problem.to_s.downcase] unless @token_list[problem.to_s.downcase].is_a?(NilClass)
238
-
239
- raise ParseError, "There is a problem around line #{num_lines}. Found <#{problem}>"
240
- end
241
-
242
191
  def parse(string)
243
192
  # First, split the string according to the "token" instructions given.
244
193
  # Afterwards @tokens contains all tokens that are to be parsed.
@@ -259,8 +208,7 @@ class Parser
259
208
  raise ParseError, 'Mismatched parenthesis! In Emacs: M-x check-parens RET'
260
209
  end
261
210
 
262
- # raise ParseError, "Parse error. expected: '#{@expected.join(', ')}', found '#{@tokens[@max_pos]}'"
263
- return find_faulty_line
211
+ return ErrorHandler.find_faulty_line(@max_pos, @file_string, @tokens, @token_list)
264
212
  end
265
213
  return result
266
214
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: alphalang
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.9
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - mattias, victor
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-05-12 00:00:00.000000000 Z
11
+ date: 2024-05-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: logger
@@ -60,6 +60,8 @@ extra_rdoc_files: []
60
60
  files:
61
61
  - bin/alphalang
62
62
  - lib/alpha.rb
63
+ - lib/error_handler.rb
64
+ - lib/error_handler.rb~
63
65
  - lib/locale_creator.rb
64
66
  - lib/locale_defaulter.rb
65
67
  - lib/locale_deleter.rb