alphalang 0.1.1 → 0.1.3
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 +41 -6
- data/lib/alpha.rb +13 -11
- data/lib/lang_creator.rb +53 -72
- data/lib/locale_deleter.rb +35 -0
- data/lib/locale_deleter.rb~ +0 -0
- data/lib/locale_lister.rb +50 -0
- data/lib/locale_lister.rb~ +0 -0
- data/lib/nodes/basenodes.rb +5 -8
- data/lib/nodes/stmtnodes.rb +81 -32
- data/lib/tester/demo_de.alpha +12 -0
- data/lib/tester/demo_sv.alpha +12 -0
- metadata +18 -13
- data/lib/nodes/#stmtnodes.rb# +0 -196
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1c31a662b58f22db4c35e2e784739c0c0def7b9ccef89ad3f06292581dfdf28d
|
4
|
+
data.tar.gz: bc02c5bfcdac5985367a5c722b88b01a4d95d35c973dcb6e61d1a05c66de23e2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7c104ae659e875f33f9b3d9ac8f358613feab8dfe56b2b166b580626994a9089c8e6ecdb307cee7b8d64e80ba0e1b63f7be7380360cf427bc18e0eb34469d966
|
7
|
+
data.tar.gz: 30f09cb6a7a6c914b0be2d84a50cd88495e482fdec29c06c49fc8d2d9bd306795a86cf26d08065b6d0da8b0b0a8458fa06cc664694c72fe546abd6f1e3adbb41
|
data/bin/alphalang
CHANGED
@@ -1,6 +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.3'.freeze
|
5
|
+
ABORT_ANSWERS = [' ', '', 'none', 'abort'].freeze # something here? Some cases empty means yes tho..
|
4
6
|
|
5
7
|
basic_error_msg = "Usage: alphalang [options] file.alpha\nUsage: alphalang -h for the help menu."
|
6
8
|
|
@@ -20,19 +22,52 @@ OptionParser.new do |opts|
|
|
20
22
|
options[:lang] = lang
|
21
23
|
end
|
22
24
|
|
23
|
-
opts.on('--createlocale', 'Creates a new locale
|
25
|
+
opts.on('--createlocale', 'Creates a new locale file for all program keywords available.') do
|
24
26
|
options[:createlocale] = true
|
25
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
|
26
40
|
end.parse!
|
27
41
|
|
28
42
|
verbose = options[:verbose]
|
29
43
|
verify = options[:verify]
|
30
44
|
language = options[:lang] || 'en'
|
31
|
-
|
45
|
+
create_locale_flag = options[:createlocale]
|
46
|
+
delete_locale_flag = options[:deletelocale]
|
47
|
+
list_locales_flag = options[:listlocales]
|
48
|
+
list_locale_flag = options[:listlocale]
|
49
|
+
|
50
|
+
if create_locale_flag
|
51
|
+
require_relative '../lib/lang_creator'
|
52
|
+
create_locale_file
|
53
|
+
return
|
54
|
+
end
|
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
|
32
67
|
|
33
|
-
if
|
34
|
-
require_relative'../lib/
|
35
|
-
|
68
|
+
if list_locale_flag
|
69
|
+
require_relative '../lib/locale_lister'
|
70
|
+
list_specific_locale_file
|
36
71
|
return
|
37
72
|
end
|
38
73
|
|
@@ -49,7 +84,7 @@ else
|
|
49
84
|
end
|
50
85
|
|
51
86
|
if verify
|
52
|
-
|
87
|
+
unless ARGV.empty?
|
53
88
|
puts 'Flag for verification found. Ignoring input file.'
|
54
89
|
sleep 1
|
55
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| ArgListNode.new(a, b) }
|
149
|
-
match(:expr) { |a| ArgListNode.new(a, NilClass) }
|
150
|
-
end
|
151
|
-
|
152
154
|
rule :prio_stmt do
|
153
155
|
match('(', :stmt, ')') { |_, a, _| a }
|
154
156
|
end
|
data/lib/lang_creator.rb
CHANGED
@@ -4,86 +4,82 @@
|
|
4
4
|
def read_translation(line)
|
5
5
|
puts "Enter the translation for: '#{line}' <RET> to accept '#{line}'"
|
6
6
|
translation = gets.chomp
|
7
|
-
translation
|
8
|
-
translation
|
7
|
+
translation.empty? ? line : translation
|
9
8
|
end
|
10
9
|
|
11
10
|
def read_translation_true_false(line)
|
12
|
-
|
13
|
-
word2 = /true/.match(line)
|
14
|
-
puts "Enter the translation for: '#{word1}' <RET> to accept '#{word1}'"
|
11
|
+
words = line.scan(/true|false/)
|
15
12
|
translation = '('
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
translation +=
|
21
|
-
end
|
22
|
-
translation += '|'
|
23
|
-
puts "Enter the translation for: '#{word2}' <RET> to accept '#{word2}'"
|
24
|
-
input2 = gets.chomp
|
25
|
-
if input2.empty?
|
26
|
-
translation += word2.to_s
|
27
|
-
else
|
28
|
-
translation += input2
|
13
|
+
words.each do |word|
|
14
|
+
puts "Enter the translation for: '#{word}' <RET> to accept '#{word}'"
|
15
|
+
input = gets.chomp
|
16
|
+
translation += input.empty? ? word : input
|
17
|
+
translation += '|'
|
29
18
|
end
|
19
|
+
translation.chop!
|
30
20
|
translation += ')'
|
31
21
|
translation
|
32
22
|
end
|
33
23
|
|
34
24
|
def read_translation_not_and_or(line)
|
35
|
-
word = /\w
|
25
|
+
word = line.match(/\w+/)[0]
|
26
|
+
postfix = line.match(/\|.+/)[0]
|
36
27
|
puts "Enter the translation for: '#{word}' <RET> to accept '#{word}'"
|
37
|
-
translation = '('
|
38
28
|
input = gets.chomp
|
39
|
-
|
40
|
-
translation += word.to_s
|
41
|
-
else
|
42
|
-
translation += input
|
43
|
-
end
|
44
|
-
translation += /\|.+/.match(line).to_s
|
45
|
-
translation
|
29
|
+
return "(#{input.empty? ? word : input}#{postfix}"
|
46
30
|
end
|
47
|
-
def create()
|
48
|
-
# Prompt the user to choose a name for the translation file
|
49
|
-
puts "Choose a name for your translation file:"
|
50
|
-
name = gets.chomp
|
51
|
-
|
52
|
-
# Create an empty file to store translations
|
53
|
-
File.open(name, 'w') {}
|
54
31
|
|
55
|
-
|
56
|
-
locale_path = File.join(__dir__, "locales", 'locale_template')
|
57
|
-
|
58
|
-
# Prompt the user to translate the line
|
32
|
+
def prompt_user(locale_template, file)
|
59
33
|
counter = 0
|
60
|
-
|
61
|
-
locale_thingies.each do |line|
|
62
|
-
|
34
|
+
locale_template.each do |line|
|
63
35
|
counter += 1
|
64
36
|
break if counter == 14
|
65
|
-
|
37
|
+
|
38
|
+
if counter < 9
|
66
39
|
translation = read_translation(line.chomp)
|
67
|
-
|
68
|
-
# Save translation after the original line
|
69
|
-
File.open(name, 'a') { |f| f.puts "#{line.chomp} #{translation}" }
|
40
|
+
File.open(file, 'a') { |f| f.puts "#{line.chomp} #{translation}" }
|
70
41
|
end
|
71
|
-
if counter == 9
|
42
|
+
if counter == 9
|
72
43
|
translation = read_translation_true_false(line.chomp)
|
73
|
-
File.open(
|
44
|
+
File.open(file, 'a') { |f| f.puts "#{line.chomp} #{translation}" }
|
74
45
|
end
|
75
46
|
if counter == 10
|
76
|
-
File.open(
|
47
|
+
File.open(file, 'a') { |f| f.puts "#{line.chomp} (==|<=|>=)" }
|
77
48
|
end
|
78
|
-
if counter > 10
|
49
|
+
if counter > 10
|
79
50
|
translation = read_translation_not_and_or(line.chomp)
|
80
|
-
File.open(
|
51
|
+
File.open(file, 'a') { |f| f.puts "#{line.chomp} #{translation}" }
|
81
52
|
end
|
53
|
+
end
|
54
|
+
end
|
82
55
|
|
56
|
+
def save_file(file)
|
57
|
+
ruby_version = "#{RUBY_VERSION}"
|
58
|
+
ruby_version[-1] = '0'
|
59
|
+
install_path = "/home/#{ENV['USER']}/.local/share/gem/ruby/#{ruby_version}/gems/alphalang-#{ALPHA_VER}"
|
60
|
+
|
61
|
+
if File.exist?(install_path)
|
62
|
+
File.rename(file, "#{install_path}/lib/locales/#{file}")
|
63
|
+
puts "Locale/syntax saved to #{install_path}/lib/locales/#{file}"
|
64
|
+
else
|
65
|
+
raise ArgumentError, "Didn't find your #{install_path}.\nTried #{ruby_version} as <VERSION>"
|
83
66
|
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def create_locale_file()
|
70
|
+
puts 'Choose a filename for your locale/syntax:'
|
71
|
+
filename = gets.chomp
|
72
|
+
File.open(filename, 'w') {}
|
73
|
+
|
74
|
+
# import locale template
|
75
|
+
locale_path = File.join(__dir__, 'locales', 'locale_template')
|
76
|
+
token_template = File.readlines(locale_path)
|
77
|
+
|
78
|
+
# prompt user for translations
|
79
|
+
prompt_user(token_template, filename)
|
84
80
|
|
85
81
|
# Append additional translations
|
86
|
-
File.open(
|
82
|
+
File.open(filename, 'a') do |f|
|
87
83
|
f.puts '\s+ \s+'
|
88
84
|
f.puts '\d+ \d+'
|
89
85
|
f.puts '\w+ \w+'
|
@@ -91,34 +87,19 @@ def create()
|
|
91
87
|
end
|
92
88
|
|
93
89
|
# Clear the screen
|
94
|
-
system(
|
90
|
+
system('clear')
|
95
91
|
|
96
92
|
# Display the contents of the translation file
|
97
|
-
puts File.read(
|
93
|
+
puts File.read(filename)
|
98
94
|
|
99
95
|
# Ask user if the translation is correct
|
100
|
-
puts
|
96
|
+
puts 'Is this correct? [Y/n]'
|
101
97
|
answer = gets.chomp
|
102
98
|
|
103
99
|
if answer.downcase == /y|Y/ or answer.empty?
|
104
|
-
|
105
|
-
|
106
|
-
# Move the translation file to the desired directory
|
107
|
-
ruby_version = "" + RUBY_VERSION.to_s
|
108
|
-
ruby_version[-1] = '0'
|
109
|
-
|
110
|
-
# Find the users installation directory and place the locale file there
|
111
|
-
if File.exist?("/home/#{ENV['USER']}/.local/share/gem/ruby/#{ruby_version}/gems/alphalang-0.1.0/lib/locales/")
|
112
|
-
File.rename(name, "/home/#{ENV['USER']}/.local/share/gem/ruby/#{ruby_version}/gems/alphalang-0.1.0/lib/locales/#{name}")
|
113
|
-
# elsif File.exist?("~/var/lib/gems/#{ruby_version}/gems/alphalang-0.1.0/lib/locales/")
|
114
|
-
# File.rename(name, "~/var/lib/gems/#{ruby_version}/gems/alphalang-0.1.0/lib/locales/#{name}")
|
115
|
-
else
|
116
|
-
raise ArgumentError, "Didn't find your .local/share/gem/ruby/<VERSION>/gems/alphalang-0.1.0
|
117
|
-
Tried Ruby <VERSION> = #{ruby_version} "
|
118
|
-
end
|
119
|
-
|
100
|
+
save_file(filename)
|
120
101
|
else
|
121
102
|
puts 'Translation removed'
|
122
|
-
File.delete(
|
103
|
+
File.delete(filename)
|
123
104
|
end
|
124
|
-
end
|
105
|
+
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
|
data/lib/nodes/basenodes.rb
CHANGED
@@ -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
|
|
@@ -38,6 +33,10 @@ class Node
|
|
38
33
|
@value = value
|
39
34
|
end
|
40
35
|
|
36
|
+
def to_s
|
37
|
+
@value
|
38
|
+
end
|
39
|
+
|
41
40
|
def evaluate
|
42
41
|
@value.evaluate
|
43
42
|
end
|
@@ -143,7 +142,6 @@ end
|
|
143
142
|
####################################################
|
144
143
|
|
145
144
|
class CompStmtNode < Node
|
146
|
-
|
147
145
|
def initialize(stmt_compstmt)
|
148
146
|
super
|
149
147
|
@comp_statements = stmt_compstmt
|
@@ -155,10 +153,9 @@ class CompStmtNode < Node
|
|
155
153
|
end
|
156
154
|
end
|
157
155
|
|
158
|
-
|
159
156
|
####################################################
|
160
157
|
|
161
|
-
class
|
158
|
+
class ArrayNode < Node
|
162
159
|
attr_accessor :lhs, :rhs
|
163
160
|
|
164
161
|
def initialize(lhs, rhs)
|
data/lib/nodes/stmtnodes.rb
CHANGED
@@ -1,26 +1,65 @@
|
|
1
1
|
require_relative 'basenodes'
|
2
2
|
|
3
3
|
####################################################
|
4
|
-
class VariableCallNode < Node
|
5
|
-
attr_accessor :name
|
6
4
|
|
7
|
-
|
8
|
-
|
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
|
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
|
-
|
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
|
-
|
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
|
-
|
90
|
+
ScopeManager.add_func_to_global_scope(@name, @value, @args)
|
53
91
|
return nil
|
54
92
|
end
|
55
93
|
end
|
@@ -62,39 +100,33 @@ 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
|
-
|
71
|
-
|
104
|
+
func = ScopeManager.lookup_func(@name)
|
105
|
+
|
72
106
|
function_body = func[0]
|
73
107
|
function_param = func[1]
|
74
108
|
|
75
|
-
|
76
|
-
|
77
|
-
$scope_lvl += 1
|
109
|
+
ScopeManager.increment_scope_level
|
78
110
|
|
79
|
-
if function_param.is_a?(
|
111
|
+
if function_param.is_a?(ArrayNode)
|
80
112
|
function_param.each do |val, index|
|
81
113
|
function_param[index] = VariableDecNode.new(function_param[index].name, @args[index])
|
82
114
|
function_param[index].evaluate
|
83
115
|
end
|
84
116
|
end
|
85
117
|
|
86
|
-
|
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
|
-
|
96
|
-
|
97
|
-
return
|
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
|
237
|
+
self.class
|
189
238
|
end
|
190
239
|
end
|
191
240
|
|
metadata
CHANGED
@@ -1,55 +1,55 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: alphalang
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- mattias
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-05-
|
11
|
+
date: 2024-05-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: logger
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '1.5'
|
20
20
|
- - ">="
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version:
|
22
|
+
version: 1.5.0
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
26
26
|
requirements:
|
27
27
|
- - "~>"
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version: '
|
29
|
+
version: '1.5'
|
30
30
|
- - ">="
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version:
|
32
|
+
version: 1.5.0
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
|
-
name:
|
34
|
+
name: optparse
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
36
36
|
requirements:
|
37
37
|
- - "~>"
|
38
38
|
- !ruby/object:Gem::Version
|
39
|
-
version: '
|
39
|
+
version: '0.3'
|
40
40
|
- - ">="
|
41
41
|
- !ruby/object:Gem::Version
|
42
|
-
version:
|
42
|
+
version: 0.3.0
|
43
43
|
type: :runtime
|
44
44
|
prerelease: false
|
45
45
|
version_requirements: !ruby/object:Gem::Requirement
|
46
46
|
requirements:
|
47
47
|
- - "~>"
|
48
48
|
- !ruby/object:Gem::Version
|
49
|
-
version: '
|
49
|
+
version: '0.3'
|
50
50
|
- - ">="
|
51
51
|
- !ruby/object:Gem::Version
|
52
|
-
version:
|
52
|
+
version: 0.3.0
|
53
53
|
description: Abstract Syntax Tree building language with a recursive descent parser
|
54
54
|
email:
|
55
55
|
- mattiasreuterskiold@gmail.com
|
@@ -61,15 +61,20 @@ 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
|
67
71
|
- lib/locales/sv
|
68
|
-
- lib/nodes/#stmtnodes.rb#
|
69
72
|
- lib/nodes/basenodes.rb
|
70
73
|
- lib/nodes/stmtnodes.rb
|
71
74
|
- lib/rdparse.rb
|
72
75
|
- lib/rdparse_quiet.rb
|
76
|
+
- lib/tester/demo_de.alpha
|
77
|
+
- lib/tester/demo_sv.alpha
|
73
78
|
- lib/tester/fibonacci.alpha
|
74
79
|
- lib/tester/test_unit.rb
|
75
80
|
homepage: https://portfolio.reuterskiold.dev
|
data/lib/nodes/#stmtnodes.rb#
DELETED
@@ -1,196 +0,0 @@
|
|
1
|
-
require_relative 'basenodes'
|
2
|
-
|
3
|
-
####################################################
|
4
|
-
class VariableCallNode < Node
|
5
|
-
attr_accessor :name
|
6
|
-
|
7
|
-
def initialize(name)
|
8
|
-
@name = name
|
9
|
-
end
|
10
|
-
|
11
|
-
def lookup_var(name)
|
12
|
-
temp_scope_lvl = $scope_lvl
|
13
|
-
while temp_scope_lvl >= 0
|
14
|
-
if not $scopes[temp_scope_lvl].has_key?(name)
|
15
|
-
temp_scope_lvl -= 1
|
16
|
-
else
|
17
|
-
return $scopes[temp_scope_lvl][name]
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def evaluate
|
23
|
-
return @value = lookup_var(@name)
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
class VariableDecNode < Node
|
28
|
-
attr_accessor :name
|
29
|
-
|
30
|
-
def initialize(name, value)
|
31
|
-
super(value)
|
32
|
-
@name = name
|
33
|
-
end
|
34
|
-
|
35
|
-
def evaluate
|
36
|
-
$scopes[$scope_lvl][@name.name] = @value.evaluate
|
37
|
-
self
|
38
|
-
# return nil
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
####################################################
|
43
|
-
|
44
|
-
class FunctionDecNode < Node
|
45
|
-
def initialize(node, value)
|
46
|
-
super(value)
|
47
|
-
@name = node
|
48
|
-
@args = node.args
|
49
|
-
end
|
50
|
-
|
51
|
-
def evaluate
|
52
|
-
$scopes[0][@name.name] = [@value, @args]
|
53
|
-
return nil
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
class FuncCallNode < Node
|
58
|
-
attr_accessor :name, :args
|
59
|
-
|
60
|
-
def initialize(name, args)
|
61
|
-
@name = name
|
62
|
-
@args = args
|
63
|
-
end
|
64
|
-
|
65
|
-
def lookup_var(name)
|
66
|
-
return $scopes[0][name]
|
67
|
-
end
|
68
|
-
|
69
|
-
def evaluate
|
70
|
-
$scopes.push({})
|
71
|
-
func = lookup_var(@name)
|
72
|
-
function_body = func[0]
|
73
|
-
function_param = func[1]
|
74
|
-
|
75
|
-
return nil if func.is_a?(NilClass)
|
76
|
-
|
77
|
-
$scope_lvl += 1
|
78
|
-
|
79
|
-
if function_param.is_a?(ArgListNode)
|
80
|
-
function_param.each do |val, index|
|
81
|
-
function_param[index] = VariableDecNode.new(function_param[index].name, @args[index])
|
82
|
-
function_param[index].evaluate
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
func_result = function_body.evaluate
|
87
|
-
old_scope_lvl = $scope_lvl
|
88
|
-
|
89
|
-
if func_result.is_a?(VariableDecNode)
|
90
|
-
$scope_lvl = 0
|
91
|
-
func_result.evaluate
|
92
|
-
$scope_lvl = old_scope_lvl
|
93
|
-
end
|
94
|
-
|
95
|
-
$scope_lvl -= 1
|
96
|
-
$scopes.pop
|
97
|
-
return func_result
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
####################################################
|
102
|
-
|
103
|
-
class IfNode < Node
|
104
|
-
attr_accessor :argument
|
105
|
-
|
106
|
-
def initialize(argument, node)
|
107
|
-
@argument, @node = argument, node
|
108
|
-
end
|
109
|
-
|
110
|
-
def evaluate
|
111
|
-
if @argument.evaluate
|
112
|
-
@value = @node.evaluate
|
113
|
-
else
|
114
|
-
@value = nil
|
115
|
-
end
|
116
|
-
@value
|
117
|
-
end
|
118
|
-
end
|
119
|
-
|
120
|
-
class ElseifNode < Node
|
121
|
-
def initialize(argument, node)
|
122
|
-
@argument, @node = argument, node
|
123
|
-
end
|
124
|
-
def evaluate
|
125
|
-
if @argument.evaluate
|
126
|
-
@value = @node.evaluate
|
127
|
-
end
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
class ElseNode < Node
|
132
|
-
def initialize(node)
|
133
|
-
@node = node
|
134
|
-
end
|
135
|
-
|
136
|
-
def evaluate
|
137
|
-
@value = @node.evaluate
|
138
|
-
end
|
139
|
-
end
|
140
|
-
|
141
|
-
class IfCompStmtNode < Node
|
142
|
-
def initialize(*nodes)
|
143
|
-
@nodes = nodes
|
144
|
-
end
|
145
|
-
def evaluate
|
146
|
-
if @nodes[0].argument.evaluate
|
147
|
-
return @nodes[0].evaluate
|
148
|
-
else
|
149
|
-
return nil if @nodes[1] == nil # hmm??
|
150
|
-
return @nodes[1].evaluate
|
151
|
-
end
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
|
-
####################################################
|
156
|
-
|
157
|
-
class WhileLoopNode < Node
|
158
|
-
attr_accessor :condition
|
159
|
-
|
160
|
-
def initialize(condition, statement)
|
161
|
-
@condition = condition
|
162
|
-
super(statement)
|
163
|
-
end
|
164
|
-
|
165
|
-
def evaluate
|
166
|
-
while @condition.evaluate
|
167
|
-
@value.evaluate
|
168
|
-
end
|
169
|
-
self.class
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
|
-
####################################################
|
174
|
-
|
175
|
-
class PrintNode
|
176
|
-
attr_accessor :value
|
177
|
-
|
178
|
-
def initialize(value)
|
179
|
-
@value = value
|
180
|
-
end
|
181
|
-
|
182
|
-
def evaluate
|
183
|
-
puts @value.evaluate
|
184
|
-
self.class # detta kanske är trevligare än nil, åter igen den diskussionen.
|
185
|
-
end
|
186
|
-
end
|
187
|
-
|
188
|
-
class PauseNode < Node
|
189
|
-
def initialize(value)
|
190
|
-
super(value)
|
191
|
-
end
|
192
|
-
|
193
|
-
def evaluate
|
194
|
-
sleep @value.evaluate
|
195
|
-
end
|
196
|
-
end
|