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 +4 -4
- data/bin/alphalang +3 -1
- data/lib/alpha.rb +70 -29
- data/lib/locale_defaulter.rb +9 -5
- data/lib/locale_lister.rb +5 -5
- data/lib/nodes/basenodes.rb +20 -20
- data/lib/nodes/scopemanager.rb +0 -2
- data/lib/nodes/stmtnodes.rb +25 -34
- data/lib/rdparse.rb +38 -63
- data/lib/tester/fibonacci.alpha +12 -2
- data/lib/tester/test_unit.rb +61 -0
- metadata +2 -2
- /data/lib/{lang_creator.rb → locale_creator.rb} +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3ab6d2758dc063b20d389b6933acbe56ab78fda4ba97f0520cc9cddb5b79701d
|
4
|
+
data.tar.gz: f14a27f54b3ab0885484ecc800bd64954bb0bce0c4740a4c1ee7113d47606a3a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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/
|
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(:
|
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, :
|
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(
|
136
|
-
match(
|
137
|
-
match(
|
138
|
-
match(
|
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
|
-
|
142
|
-
|
143
|
-
|
144
|
-
match(
|
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]
|
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
|
data/lib/locale_defaulter.rb
CHANGED
@@ -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 |
|
9
|
-
if
|
10
|
-
|
11
|
-
|
12
|
-
|
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
|
|
data/lib/nodes/basenodes.rb
CHANGED
@@ -1,6 +1,4 @@
|
|
1
|
-
|
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
|
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
|
data/lib/nodes/scopemanager.rb
CHANGED
data/lib/nodes/stmtnodes.rb
CHANGED
@@ -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
|
-
|
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
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
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
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
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
|
-
|
211
|
+
result
|
210
212
|
end
|
211
213
|
|
212
|
-
def
|
213
|
-
|
214
|
-
|
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
|
-
|
219
|
-
|
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
|
-
|
228
|
+
pattern = file_as_array_without_whitespaces.join('\s*')
|
229
|
+
regex = Regexp.new(pattern)
|
235
230
|
|
236
|
-
|
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
|
-
|
242
|
-
|
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
|
-
|
247
|
-
|
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
|
-
|
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)
|
data/lib/tester/fibonacci.alpha
CHANGED
data/lib/tester/test_unit.rb
CHANGED
@@ -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.
|
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/
|
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
|