alphalang 0.2.6 → 0.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6dbe6c0cb099f96c68feadb26492b409cdb71d2db52fd5e6436a6c142d273584
4
- data.tar.gz: 215b6ea3d011610dbdb3d2021025c29361df8d6cc4dba74a7a8dabf0d7596fdb
3
+ metadata.gz: 3ab6d2758dc063b20d389b6933acbe56ab78fda4ba97f0520cc9cddb5b79701d
4
+ data.tar.gz: f14a27f54b3ab0885484ecc800bd64954bb0bce0c4740a4c1ee7113d47606a3a
5
5
  SHA512:
6
- metadata.gz: c99ce78b496f2eb91ddb26c799fe51e18e5fb0f2d23d546fcadff0cc7a293c28af455ecad577d43b1e9c4e156f781d17b9ba4b4f7f856861158b68301c23ef77
7
- data.tar.gz: d6fd552131866752356ce35a82c1ce032dc1863597b1ba618e9f9924fc1d9c2c86a8e595fe64358757156150125ba937350bd422e5818f77f453be9be0882a1a
6
+ metadata.gz: ceddb38213e3e95d0156a12e0fdd5461cf7880d0c517603ca2117276f5f5db22630598afa6e8d0d66aa4865b3eacc947b09edc78f3660c20e9e2c07e4a633b5b
7
+ data.tar.gz: 347feeb1bc8ec3fa97f4b1bbd529bb071894f604e9bd534749cd4ab198e83c20da0c02c0f3d4ba016d5e249937ccc3f9ee33235d538262bf3ae0279a705c60b3
data/bin/alphalang CHANGED
@@ -56,7 +56,7 @@ list_locales_flag = options[:listlocales]
56
56
  list_locale_flag = options[:listlocale]
57
57
 
58
58
  if create_locale_flag
59
- require_relative '../lib/lang_creator'
59
+ require_relative '../lib/locale_creator'
60
60
  create_locale_file
61
61
  return
62
62
  end
@@ -104,7 +104,9 @@ if verify_flag
104
104
  puts 'Flag for verification found. Ignoring input file.'
105
105
  sleep 1
106
106
  end
107
+ TEST_UNIT_ACTIVE = true
107
108
  require_relative '../lib/tester/test_unit'
108
109
  else
110
+ TEST_UNIT_ACTIVE = false
109
111
  LangParser.new(language_flag, verbose_flag).parse_file(ARGV[0])
110
112
  end
data/lib/alpha.rb CHANGED
@@ -36,31 +36,48 @@ class LangParser
36
36
  match(:stmt)
37
37
  end
38
38
 
39
+ ###################### Statement Rules
40
+
39
41
  rule :stmt do
40
42
  match(:if_comp_stmt)
43
+ match(:loop)
44
+ match(:declaration)
45
+ match(:builtin)
46
+ match(:expr_stmt)
47
+ end
48
+
49
+ rule :loop do
41
50
  match(:while_stmt)
51
+ end
52
+
53
+ rule :declaration do
42
54
  match(:func_dec)
43
55
  match(:ass_stmt)
56
+ end
57
+
58
+ rule :builtin do
44
59
  match(:pause_stmt)
45
- match(:expr_stmt)
60
+ match(:print_stmt)
46
61
  end
47
62
 
63
+ ###################### If Statement Rules
64
+
48
65
  rule :if_comp_stmt do
49
66
  match(:if_stmt, :comp_elseif, :else_stmt, :STOP) { |a, b, c| IfCompStmtNode.new(a, b, c) }
50
67
  match(:if_stmt, :else_stmt, :STOP) { |a, b| IfCompStmtNode.new(a, b) }
51
68
  match(:if_stmt, :STOP) { |a| IfCompStmtNode.new(a) }
52
69
  end
53
70
 
54
- rule :comp_elseif do
55
- match(:elseif_stmt, :comp_elseif) { |a, b| [a, b] }
56
- match(:elseif_stmt)
57
- end
58
-
59
71
  rule :if_stmt do
60
72
  match(:IF, :expr_stmt, :and, :expr_stmt, :comp_stmt) { |_, a, b, c, d| IfCompactNode.new(a, b, c, d) }
61
73
  match(:IF, :expr_stmt, :comp_stmt) { |_, a, b| IfNode.new(a, b) }
62
74
  end
63
75
 
76
+ rule :comp_elseif do
77
+ match(:elseif_stmt, :comp_elseif) { |a, b| [a, b] }
78
+ match(:elseif_stmt)
79
+ end
80
+
64
81
  rule :elseif_stmt do
65
82
  match(:ELSEIF, :expr_stmt, :comp_stmt) { |_, a, b| ElseifNode.new(a, b) }
66
83
  end
@@ -69,12 +86,16 @@ class LangParser
69
86
  match(:ELSE, :comp_stmt) { |_, b| ElseNode.new(b) }
70
87
  end
71
88
 
89
+ ###################### Loop Rules
90
+
72
91
  rule :while_stmt do
73
92
  match(:WHILE, :expr_stmt, :comp_stmt, :STOP) { |_, a, b| WhileLoopNode.new(a, b) }
74
93
  end
75
94
 
95
+ ###################### Variable and Function Declare Rules
96
+
76
97
  rule :func_dec do
77
- match(:DEF, :member, :comp_stmt, :STOP) { |_, name, value, _| FunctionDecNode.new(name, value) }
98
+ match(:DEF, :call_member, :comp_stmt, :STOP) { |_, name, value, _| FunctionDecNode.new(name, value) }
78
99
  end
79
100
 
80
101
  rule :ass_stmt do
@@ -82,10 +103,18 @@ class LangParser
82
103
  match(:member, '=', :array_stmt) { |var, _, value| VariableDecNode.new(var, value) }
83
104
  end
84
105
 
106
+ ###################### Built-In Function Rules
107
+
85
108
  rule :pause_stmt do
86
109
  match(:PAUSE, :expr) { |_, a| PauseNode.new(a) }
87
110
  end
88
111
 
112
+ rule :print_stmt do
113
+ match(:PRINT, :expr) { |_, a| PrintNode.new(a) }
114
+ end
115
+
116
+ ###################### Expression Rules
117
+
89
118
  rule :expr_stmt do
90
119
  match(:or_stmt)
91
120
  match(:and_stmt)
@@ -105,15 +134,6 @@ class LangParser
105
134
  match(:NOT, :expr_stmt) { |_, b| NotNode.new(b) }
106
135
  end
107
136
 
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
-
117
137
  rule :expr do
118
138
  match(:expr, /(<|>)/, :expr) { |a, op, b| CompareNode.new(a, op, b) }
119
139
  match(/(<|>)/, :expr) { |op, b| CompareNode.new(nil, op, b) }
@@ -131,25 +151,46 @@ class LangParser
131
151
  match(:atom)
132
152
  end
133
153
 
154
+ ###################### Data Types Rules
155
+
156
+ rule :array_stmt do
157
+ match('[', :arg_list, ']') { |_, array, _| array }
158
+ end
159
+
160
+ rule :arg_list do
161
+ match(:expr, ',', :arg_list) { |a, _, b| ArrayNode.new(a, b) }
162
+ match(:expr) { |a| ArrayNode.new(a, NilClass) }
163
+ end
164
+
134
165
  rule :atom do
135
- match('-', /\d+/, '.', /\d+/) { |neg, a, dot, b| NumberNode.new((neg+a+dot+b)) }
136
- match(/\d+/, '.', /\d+/) { |a, dot, b| NumberNode.new((a+dot+b)) }
137
- match('-', /\d+/) { |neg, a| NumberNode.new(neg + a) }
138
- match(/\d+/) { |a| NumberNode.new(a) }
166
+ match(:number)
167
+ match(:boolean)
168
+ match(:call_member)
169
+ match(:prio_stmt)
170
+ end
171
+
172
+ rule :boolean do
139
173
  match(ScopeManager.true_value) { |a| BoolNode.new(a) }
140
174
  match(ScopeManager.false_value) { |a| BoolNode.new(a) }
141
- match(:PRINT, :member) { |_, a| PrintNode.new(a) }
142
- match(:PRINT, :expr) { |_, a| PrintNode.new(a) }
143
- match(:member)
144
- match(:prio_stmt)
175
+ end
176
+
177
+ rule :number do
178
+ match('-', /\d+/, '.', /\d+/) { |neg, a, dot, b| NumberNode.new(neg + a + dot + b) }
179
+ match(/\d+/, '.', /\d+/) { |a, dot, b| NumberNode.new(a + dot + b) }
180
+ match('-', /\d+/) { |neg, a| NumberNode.new(neg + a) }
181
+ match(/\d+/) { |a| NumberNode.new(a) }
182
+ end
183
+
184
+ rule :call_member do
185
+ match(:member, '(', :arg_list, ')') { |var, _, args, _| FuncCallNode.new(var, args) }
186
+ match(:member, '(', ')') { |var, _, _| FuncCallNode.new(var, NilClass) }
187
+ match(:member, '[', '-', /\d+/, ']') { |var, _, neg, index, _| ArrayCallNode.new(var, (neg+index)) }
188
+ match(:member, '[', /\d+/, ']') { |var, _, index, _| ArrayCallNode.new(var, index) }
189
+ match(:member) { |var| VariableCallNode.new(var) }
145
190
  end
146
191
 
147
192
  rule :member do
148
- match(/[a-z]/, '(', :arg_list, ')') { |var, _, args, _| FuncCallNode.new(var, args) }
149
- match(/[a-z]/, '(', ')') { |var, _, _| FuncCallNode.new(var, NilClass) }
150
- match(/[a-z]/, '[', '-', /\d+/, ']') { |var, _, neg, index, _| ArrayCallNode.new(var, (neg+index)) }
151
- match(/[a-z]/, '[', /\d+/, ']') { |var, _, index, _| ArrayCallNode.new(var, index) }
152
- match(/[a-z]/) { |var| VariableCallNode.new(var) }
193
+ match(/[a-z]/)
153
194
  end
154
195
 
155
196
  rule :prio_stmt do
@@ -5,11 +5,15 @@ require_relative 'locale_lister'
5
5
  def set_default_locale(new_locale)
6
6
  available_locales = get_locale_files
7
7
 
8
- available_locales.each do |locale|
9
- if locale == new_locale
10
- File.open("#{LOCALES_PATH}/default", 'w') { |f| f.write(new_locale)}
11
- puts "[alphalang] Default syntax locale is now set to #{locale}."
12
- return
8
+ available_locales.each do |available_locale|
9
+ if available_locale == new_locale
10
+ begin
11
+ File.open("#{LOCALES_PATH}/default", 'w') { |f| f.write(new_locale) }
12
+ puts "[alphalang] Default syntax locale is now set to #{new_locale}."
13
+ rescue Errno::ENOENT
14
+ puts '[alphalang] Failed to change default locale. Likely permissions error on your machine.'
15
+ puts "Could not open #{LOCALES_PATH}/default}"
16
+ end
13
17
  end
14
18
  end
15
19
  end
data/lib/locale_lister.rb CHANGED
@@ -30,22 +30,24 @@ end
30
30
 
31
31
  def print_clean_locale_array(locale_name, clean_array)
32
32
  longest_word = clean_array.max_by(&:length).size
33
- padding = ' ' * (longest_word/2-5)
33
+ padding = ' ' * (longest_word / 2 - 5)
34
34
 
35
35
  header = "#{padding}[alphalang] Syntax for locale <#{locale_name}>.#{padding}"
36
36
  puts header
37
37
  puts '+' * (header.size - 2)
38
+
38
39
  clean_line = ''
39
40
  clean_array.each_with_index do |word, index|
40
41
  if index.even?
41
42
  clean_line += "+ #{word}"
42
43
  else
43
- clean_line += (' ' * (20 -clean_line.size)) + "#{word}"
44
+ clean_line += (' ' * (20 - clean_line.size)) + "#{word}"
44
45
  clean_line += (' ' * (header.size - clean_line.size - 3) + '+')
45
46
  puts clean_line
46
47
  clean_line = ''
47
48
  end
48
49
  end
50
+
49
51
  puts '+' * (header.size - 2)
50
52
  end
51
53
 
@@ -53,9 +55,7 @@ def list_specific_locale_file()
53
55
  list_locale_files
54
56
  specific_locale = gets.chomp
55
57
 
56
- if specific_locale == 'default'
57
- specific_locale = File.read("#{LOCALES_PATH}/#{specific_locale}")
58
- end
58
+ specific_locale = File.read("#{LOCALES_PATH}/#{specific_locale}") if specific_locale == 'default'
59
59
 
60
60
  return if ABORT_ANSWERS.include?(specific_locale)
61
61
 
@@ -1,6 +1,4 @@
1
- #!/usr/bin/env ruby
2
-
3
- ####################################################
1
+ ###################### Base Nodes
4
2
 
5
3
  class Node
6
4
  attr_accessor :value
@@ -43,6 +41,8 @@ class BoolNode < Node
43
41
  end
44
42
  end
45
43
 
44
+ ###################### Logic Gate Nodes
45
+
46
46
  class AndNode < Node
47
47
  def initialize(lhs, rhs)
48
48
  @lhs, @rhs = lhs, rhs
@@ -83,7 +83,7 @@ class NotNode < Node
83
83
  end
84
84
  end
85
85
 
86
- ####################################################
86
+ ###################### Operation Nodes
87
87
 
88
88
  class CompareNode < Node
89
89
  attr_accessor :lhs, :op, :rhs
@@ -119,7 +119,7 @@ class BinaryOperationNode < Node
119
119
  end
120
120
 
121
121
  if @rhs.evaluate.is_a?(ArrayNode) or @rhs.evaluate.is_a?(Array) and @lhs.evaluate.is_a?(Numeric)
122
- raise SyntaxError, "You can't subtract and array from a number! #{@lhs.evaluate} #{@op} #{@rhs.name}"
122
+ raise SyntaxError, "You can't subtract an array from a number! #{@lhs.evaluate} #{@op} #{@rhs.name}"
123
123
  end
124
124
 
125
125
  if @op == '/'
@@ -130,21 +130,7 @@ class BinaryOperationNode < Node
130
130
  end
131
131
  end
132
132
 
133
- ####################################################
134
-
135
- class CompStmtNode < Node
136
- def initialize(stmt_compstmt)
137
- super
138
- @comp_statements = stmt_compstmt
139
- end
140
-
141
- def evaluate
142
- @comp_statements[0].evaluate
143
- @comp_statements[1].evaluate
144
- end
145
- end
146
-
147
- ####################################################
133
+ ###################### Array / Data Structure Nodes
148
134
 
149
135
  class ArrayNode < Node
150
136
  attr_accessor :lhs, :rhs
@@ -205,3 +191,17 @@ class ArrayNode < Node
205
191
  self
206
192
  end
207
193
  end
194
+
195
+ ###################### Root Program Node
196
+
197
+ class CompStmtNode < Node
198
+ def initialize(stmt_compstmt)
199
+ super
200
+ @comp_statements = stmt_compstmt
201
+ end
202
+
203
+ def evaluate
204
+ @comp_statements[0].evaluate
205
+ @comp_statements[1].evaluate
206
+ end
207
+ end
@@ -2,8 +2,6 @@ require_relative 'stmtnodes'
2
2
 
3
3
  ####################################################
4
4
 
5
- $test_nodes = false
6
-
7
5
  class ScopeManager
8
6
  def initialize(true_value, false_value)
9
7
  @@true_value = true_value
@@ -1,6 +1,6 @@
1
1
  require_relative 'basenodes'
2
2
 
3
- ####################################################
3
+ ###################### Variable Nodes
4
4
 
5
5
  class VariableCallNode < Node
6
6
  attr_accessor :name
@@ -29,7 +29,22 @@ class VariableDecNode < Node
29
29
  end
30
30
  end
31
31
 
32
- ####################################################
32
+ class ArrayCallNode < Node
33
+ def initialize(array, index)
34
+ super(array)
35
+ @index = index.to_i
36
+ end
37
+
38
+ def evaluate
39
+ arr = ScopeManager.lookup_var(@value)
40
+ if @index > arr.size - 1
41
+ raise ArgumentError, "You are trying to access an out of bounds index. Here -> #{@value}[#{@index}]"
42
+ end
43
+ @value = arr[@index]
44
+ end
45
+ end
46
+
47
+ ###################### Function Nodes
33
48
 
34
49
  class FunctionDecNode < Node
35
50
  def initialize(node, value)
@@ -84,7 +99,7 @@ class FuncCallNode < Node
84
99
  end
85
100
  end
86
101
 
87
- ####################################################
102
+ ###################### If Statement Nodes
88
103
 
89
104
  class IfNode < Node
90
105
  attr_accessor :argument
@@ -138,7 +153,7 @@ class IfCompStmtNode < Node
138
153
  end
139
154
  end
140
155
 
141
- ####################################################
156
+ ###################### Loop Nodes
142
157
 
143
158
  class WhileLoopNode < Node
144
159
  attr_accessor :condition
@@ -156,24 +171,7 @@ class WhileLoopNode < Node
156
171
  end
157
172
  end
158
173
 
159
- ####################################################
160
-
161
- class ArrayCallNode < Node
162
- def initialize(array, index)
163
- super(array)
164
- @index = index.to_i
165
- end
166
-
167
- def evaluate
168
- arr = ScopeManager.lookup_var(@value)
169
- if @index > arr.size - 1
170
- raise ArgumentError, "You are trying to access an out of bounds index. Here -> #{@value}[#{@index}]"
171
- end
172
- @value = arr[@index]
173
- end
174
- end
175
-
176
- ####################################################
174
+ ###################### Built-in Functions
177
175
 
178
176
  class PrintNode
179
177
  attr_accessor :value
@@ -184,20 +182,13 @@ class PrintNode
184
182
 
185
183
  def evaluate
186
184
  if @value.evaluate.is_a?(ArrayNode)
187
- print "Array #{@value.name}: "
188
- puts @value.evaluate
185
+ print "Array #{@value.name}: " unless TEST_UNIT_ACTIVE
186
+ puts @value.evaluate unless TEST_UNIT_ACTIVE
189
187
  elsif @value.evaluate.is_a?(Array)
190
- print "Array #{@value.name}: "
191
- puts @value.evaluate.join(', ')
188
+ print "Array #{@value.name}: " unless TEST_UNIT_ACTIVE
189
+ puts @value.evaluate.join(', ') unless TEST_UNIT_ACTIVE
192
190
  else
193
- if @value.evaluate == PrintNode
194
- if @value.value.is_a?(VariableCallNode)
195
- raise SyntaxError, "You have a duplicate 'print' statement! Printing #{@value.value.name} twice."
196
- else
197
- raise SyntaxError, "You have a duplicate 'print' statement! Printing #{@value.value} twice."
198
- end
199
- end
200
- puts @value.evaluate
191
+ puts @value.evaluate unless TEST_UNIT_ACTIVE
201
192
  end
202
193
  self.class
203
194
  end
data/lib/rdparse.rb CHANGED
@@ -187,81 +187,56 @@ class Parser
187
187
  end # until
188
188
  end
189
189
 
190
- def find_faulty_expression_within_block(block_start_line, block_end_line, problematic_token)
191
- if block_start_line == nil || block_end_line == nil
192
- raise ParseError, "Error with <#{problematic_token}> somewhere around line #{block_end_line}#{block_start_line}"
193
- end
194
- index = 0
195
- result = []
196
- @file_string.each_line do |line|
197
- if index > block_start_line and index < block_end_line
198
-
199
- if line.match?(/;;.*$/)
200
- line = line.split(';;')[0]
201
- end
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
202
203
 
203
- if line.match?(/#{problematic_token}\s+$/)
204
- result << "ParseError, #{line.strip}() is missing an expression on line #{index + 1}"
205
- end
206
- end
207
- index += 1
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)
208
210
  end
209
- raise ParseError, result[-1]
211
+ result
210
212
  end
211
213
 
212
- def find_faulty_expression_within_ends
213
- puts 'TODO: Implement search for faulty token between two of the same guides'
214
- raise ParseError, "Most likely mismatched '#{@token_list['END'.downcase]}' token."
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
215
222
  end
216
223
 
217
224
  def find_faulty_line
218
- if @tokens[@max_pos-0].is_a?(NilClass)
219
- if @max_pos >= 3
220
- puts "Problem is in the end of the file after:\n #{@tokens[@max_pos - 3]}#{@tokens[@max_pos - 2]}#{@tokens[@max_pos - 1]}"
221
- else
222
- puts "Problem is right in the beginning of the file."
223
- end
224
- raise ParseError
225
- end
226
-
227
- problematic_token = "#{@tokens[@max_pos - 1].downcase}"
228
- before_problem = "#{@tokens[@max_pos - 2].downcase}"
229
- after_problem = "#{@tokens[@max_pos - 0].downcase}"
230
-
231
- after_problem = "[" + after_problem + "]" if !after_problem.match?(/[a-z]/)
232
- before_problem = "[" + before_problem + "]" if !before_problem.match?(/[a-z]/)
225
+ tokens_before_problem = find_surrounding_code(@max_pos - 1)
226
+ file_as_array_without_whitespaces = translate_tokens_array(tokens_before_problem)
233
227
 
234
- translated_problematic_token = @token_list[problematic_token]
228
+ pattern = file_as_array_without_whitespaces.join('\s*')
229
+ regex = Regexp.new(pattern)
235
230
 
236
- if translated_problematic_token.is_a?(NilClass)
237
- puts "The problem is #{before_problem}#{problematic_token}#{after_problem}"
238
- raise ParseError, "Faulty expression, this is not completely implemented."
239
- end
231
+ cleaned_string = @file_string.gsub(/;;.*/, '')
240
232
 
241
- index = 0
242
- problem_match_hash = {}
243
- found_end = false
244
- @file_string.each_line do |line|
233
+ match_data = regex.match(cleaned_string)
234
+ num_lines = match_data[0].count("\n") + 1
245
235
 
246
- if line.match?(before_problem) && found_end == false
247
- problem_match_hash[before_problem] = index
248
- end
236
+ problem = @tokens[@max_pos]
237
+ problem = @token_list[problem.to_s.downcase] unless @token_list[problem.to_s.downcase].is_a?(NilClass)
249
238
 
250
- if line.match?(after_problem) && index > problem_match_hash[before_problem]
251
- problem_match_hash[after_problem] = index
252
- found_end = true
253
- end
254
- index += 1
255
- end
256
-
257
- non_empty_line_before_problem = problem_match_hash[before_problem]
258
- non_empty_line_after_problem = problem_match_hash[after_problem]
259
-
260
- unless after_problem == before_problem
261
- find_faulty_expression_within_block(non_empty_line_before_problem, non_empty_line_after_problem, problematic_token)
262
- else
263
- find_faulty_expression_within_ends
264
- end
239
+ raise ParseError, "There is a problem around line #{num_lines}. Found <#{problem}>"
265
240
  end
266
241
 
267
242
  def parse(string)
@@ -1,7 +1,17 @@
1
1
  a = 1
2
2
  b = 1
3
- print b
3
+
4
4
  def fib(x)
5
+ if 2 < x
6
+
7
+ temp = a + b
8
+ a = b
9
+ b = temp
10
+
11
+ fib(x - 1)
12
+ else
13
+ b
14
+ end
5
15
  end
6
16
 
7
- fib(100)
17
+ print fib(11)
@@ -239,3 +239,64 @@ class TesCompactIf < Test::Unit::TestCase
239
239
  #{$end}"))
240
240
  end
241
241
  end
242
+
243
+ class TestPrograms < Test::Unit::TestCase
244
+ def test_fibonacci
245
+ program = "
246
+ a = 1
247
+ b = 1
248
+
249
+ #{$def} fib(x)
250
+ #{$if} 2 < x
251
+
252
+ temp = a + b
253
+ a = b
254
+ b = temp
255
+
256
+ fib(x - 1)
257
+ #{$else}
258
+ b
259
+ #{$end}
260
+ #{$end}
261
+
262
+ fib(11)
263
+ "
264
+ assert_equal(89, LangParser.new.calc_test(program))
265
+ end
266
+
267
+ def test_func_with_while
268
+ program = "
269
+ x = 1
270
+
271
+ #{$def} foo(bar)
272
+ #{$while} bar < 20
273
+ #{$print} bar
274
+ bar = bar + 1
275
+ #{$end}
276
+ #{$end}
277
+
278
+ foo(x)
279
+ "
280
+ assert_equal(WhileLoopNode, LangParser.new.calc_test(program))
281
+ end
282
+
283
+ def test_func_with_while_return_value
284
+ program = "
285
+ x = 1
286
+
287
+ #{$def} foo(bar)
288
+ y = 0
289
+ #{$while} bar < 20
290
+ #{$print} bar
291
+ bar = bar + 1
292
+ y = bar
293
+ #{$end}
294
+ #{$print} y
295
+ y
296
+ #{$end}
297
+
298
+ foo(x)
299
+ "
300
+ assert_equal(20, LangParser.new.calc_test(program))
301
+ end
302
+ end
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.2.6
4
+ version: 0.2.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - mattias, victor
@@ -60,7 +60,7 @@ extra_rdoc_files: []
60
60
  files:
61
61
  - bin/alphalang
62
62
  - lib/alpha.rb
63
- - lib/lang_creator.rb
63
+ - lib/locale_creator.rb
64
64
  - lib/locale_defaulter.rb
65
65
  - lib/locale_deleter.rb
66
66
  - lib/locale_lister.rb
File without changes