alphalang 0.2.9 → 0.3.0

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: 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