mvinl 0.1.5 → 0.1.6

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: 4ceac64e8ec7e1ff3f8fab41d82d4b69a577098bca195f7ed01205dfc3b54b2d
4
- data.tar.gz: f8592113d9ac37d001048f8f49c4e46e4c1f09d6209e32800f73f821549fab61
3
+ metadata.gz: 7c681f294e44a200c6fb8c66aed4ac1c50fce869c1c12f0a64b891b0ee720842
4
+ data.tar.gz: 94acd6d0220cb2fbfa05c839e8081e19b6d8ef3c3f4bd549dec217653b53fe0a
5
5
  SHA512:
6
- metadata.gz: e31891e65cde3f3de7124ec7665eaf89561f3a5db04201e03c316ee214e09b5d67db5f79d108eee5ddeae30daaddea187dbe27bcec2881aa7ff1bb4970b50536
7
- data.tar.gz: 2b05bef7791eec6129ba210fd146f3ea575098d7ab70afe44cf709297319d2915ad7d5c876cf0dfe64a9f177dc299bb46a17a3769ed40d0317b77d6d0ebdbeb2
6
+ metadata.gz: 2d2df258513050c3c8b982865df1e60e2d84aa253b09070f65ae0775d9a07f90231480130d5e9b645b0ee761460d66acf097a35e878894f7b30d3eda62ab23ed
7
+ data.tar.gz: 5eaa3496bef0fc23371cf449e12264873fa6455bff81f88c70c454a903b09b2860252feec4e07515d3eb37a637f2fdad7ffabfd1ad4dd5758e19844641cbf868
data/bin/imvnl CHANGED
@@ -24,25 +24,28 @@ THE SOFTWARE.
24
24
  =end
25
25
 
26
26
  require 'readline'
27
- require 'pry'
27
+ require 'mvinl/context'
28
28
  require 'mvinl/lexer'
29
29
  require 'mvinl/parser'
30
- require 'mvinl/context'
31
30
  require 'mvinl/info'
32
31
 
33
- PSL = "mvnl(#{MVinl::Version})".freeze
34
- PS1 = "#{PSL}>".freeze
35
-
36
32
  module MVinl::REPL
33
+ PSL = "mvnl(#{MVinl::Version})".freeze
34
+ PS1 = "#{PSL}>".freeze
35
+ HISTORY_FILE = File.expand_path('.imvnl_history')
37
36
  CONTEXT = MVinl::Context.new
38
37
  LEXER = MVinl::Lexer.new(CONTEXT, '')
39
38
  PARSER = MVinl::Parser.new(LEXER, CONTEXT)
40
39
 
41
40
  def self.run
41
+ load_history
42
+
42
43
  while (input = Readline.readline("#{PS1} ", true))
43
- Readline::HISTORY.pop if input.strip.empty?
44
+ if Readline::HISTORY.size > 1 && Readline::HISTORY[-1] == Readline::HISTORY[-2]
45
+ Readline::HISTORY.pop
46
+ end
44
47
 
45
- if input == '^' || input == 'exit'
48
+ if ['^', 'exit'].include? input
46
49
  PARSER.finalize!
47
50
  break if PARSER.parsing_done?
48
51
  else
@@ -61,6 +64,22 @@ module MVinl::REPL
61
64
  warn e.message
62
65
  end
63
66
  end
67
+
68
+ save_history
69
+ end
70
+
71
+ private_class_method def self.load_history
72
+ return unless File.exist? HISTORY_FILE
73
+
74
+ File.foreach(HISTORY_FILE) do |line|
75
+ Readline::HISTORY << line.chomp
76
+ end
77
+ end
78
+
79
+ private_class_method def self.save_history
80
+ File.open(HISTORY_FILE, 'w') do |file|
81
+ Readline::HISTORY.each { |entry| file.puts(entry) }
82
+ end
64
83
  end
65
84
  end
66
85
 
data/lib/mvinl/context.rb CHANGED
@@ -1,10 +1,15 @@
1
1
  # frozen-string-literal: true
2
2
 
3
+ require 'pry'
4
+
3
5
  module MVinl
4
6
  # Lexer and parser shared context
5
7
  class Context
6
8
  attr_accessor :variables, :functions, :state
7
9
 
10
+ RESERVED = %I[def]
11
+ CONSTANTS = {}
12
+
8
13
  def initialize
9
14
  reset
10
15
  end
@@ -17,8 +22,33 @@ module MVinl
17
22
  in_var: false,
18
23
  in_keyword_arg: false,
19
24
  keyword_arg_depth: 0,
25
+ lines: 0,
20
26
  depth: 0
21
27
  }
22
28
  end
29
+
30
+ def define_function(name, args, body)
31
+ @functions[name] = { args: args, body: body }
32
+ end
33
+
34
+ def define_constant(name, value)
35
+ if RESERVED.include? name
36
+ nil
37
+ elsif CONSTANTS[name]
38
+ false
39
+ else
40
+ @state[:in_var] = false
41
+ CONSTANTS[name] = value
42
+ end
43
+ end
44
+
45
+ def define_variable(name, value)
46
+ if RESERVED.include? name
47
+ nil
48
+ else
49
+ @state[:in_var] = false
50
+ @variables[name] = value
51
+ end
52
+ end
23
53
  end
24
54
  end
data/lib/mvinl/info.rb CHANGED
@@ -6,7 +6,7 @@
6
6
  # See Copyright Notice in mvnil.rb
7
7
 
8
8
  module MVinl
9
- VERSION = '0.1.5'
9
+ VERSION = '0.1.6'
10
10
  Version = VERSION
11
11
  Copyright = 'Copyright (c) 2024, Daniel Sierpiński'
12
12
  end
data/lib/mvinl/lexer.rb CHANGED
@@ -16,11 +16,8 @@ module MVinl
16
16
  attr_reader :eos
17
17
 
18
18
  ID_REGEX = /[a-zA-Z_][a-zA-Z0-9_]*/
19
-
20
- RESERVED = %w[def as style].freeze
21
-
22
19
  TOKENS = {
23
- KEYWORD: /#{RESERVED[0]}|#{RESERVED[1]}|#{RESERVED[2]}/,
20
+ KEYWORD: Regexp.union(Context::RESERVED),
24
21
  OPEN_PAREN: /\(/,
25
22
  CLOSE_PAREN: /\)/,
26
23
  NEW_LINE: /(?:[ \t]*(?:\r?\n)[ \t]*)+/,
@@ -28,6 +25,7 @@ module MVinl
28
25
  KEYWORD_ARG: /(#{ID_REGEX}):/,
29
26
  ID: ID_REGEX,
30
27
  GROUP: /@(#{ID_REGEX})/,
28
+ CONSTANT: /!([A-Z][A-Z0-9_]*)/,
31
29
  VARIABLE: /!(#{ID_REGEX})/,
32
30
  FLOAT: /[+-]?\d+\.\d+/,
33
31
  NUMBER: /[+-]?\d+/,
@@ -55,8 +53,11 @@ module MVinl
55
53
  return process_eos if @ss.eos?
56
54
 
57
55
  # Check if variable name been used
56
+ MVinl::Context::CONSTANTS.each_key do |const_name|
57
+ return [:CONSTANT_CALL, const_name] if @ss.scan(/\A#{Regexp.escape const_name.to_s}\b/)
58
+ end
58
59
  @context.variables.each_key do |var_name|
59
- return [:VARIABLE_CALL, @context.variables[var_name]] if @ss.scan(/\A#{Regexp.escape var_name.to_s}\b/)
60
+ return [:VARIABLE_CALL, var_name] if @ss.scan(/\A#{Regexp.escape var_name.to_s}\b/)
60
61
  end
61
62
 
62
63
  TOKENS.each do |type, regex|
@@ -67,6 +68,7 @@ module MVinl
67
68
  end
68
69
  case @last_type
69
70
  when :NEW_LINE
71
+ @context.state[:lines] += 1
70
72
  return next_token if continuation_line?
71
73
 
72
74
  [:END_TAG, "\n"]
@@ -110,6 +112,7 @@ module MVinl
110
112
 
111
113
  @in_group = true
112
114
  [:GROUP, @ss[1]]
115
+ when :CONSTANT then [:CONSTANT, @ss[1]]
113
116
  when :VARIABLE then [:VARIABLE, @ss[1]]
114
117
  when :ID then [:ID, @ss.matched]
115
118
  when :NUMBER, :FLOAT, :STRING, :SYMBOL, :MULTILINE_STRING
data/lib/mvinl/parser.rb CHANGED
@@ -21,6 +21,9 @@ class MVinl::Parser < MVinl::Program
21
21
 
22
22
  def parse
23
23
  do_parse
24
+ rescue Racc::ParseError => e
25
+ puts "Parsing error at #{@context.state[:lines]}: #{e.message}"
26
+ nil
24
27
  end
25
28
 
26
29
  def feed(input)
data/lib/mvinl.rb CHANGED
@@ -22,9 +22,9 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
22
  THE SOFTWARE.
23
23
  =end
24
24
 
25
+ require 'mvinl/context'
25
26
  require 'mvinl/parser'
26
27
  require 'mvinl/lexer'
27
- require 'mvinl/context'
28
28
 
29
29
  # Library entry point
30
30
  module MVinl
@@ -0,0 +1,5 @@
1
+ !a 5
2
+ def (foo (* a 2))
3
+ !a 10
4
+
5
+ x (foo)
@@ -0,0 +1,5 @@
1
+ !a "Hello," \
2
+ "MVinl" \
3
+ "!"
4
+
5
+ x a
data/spec/program_spec.rb CHANGED
@@ -1,8 +1,6 @@
1
1
  # frozen-string-literal: true
2
2
 
3
3
  require_relative 'spec_helper'
4
- require 'mvinl'
5
- require 'pry'
6
4
 
7
5
  describe MVinl, '#eval' do
8
6
  context 'no input' do
@@ -39,7 +37,7 @@ describe MVinl, '#eval' do
39
37
  MVinl.eval('!n 0')
40
38
  expect(MVinl.context.variables[:n]).to be_truthy
41
39
  end
42
- it 'stores a two variables' do
40
+ it 'stores two variables' do
43
41
  MVinl.eval('!n 3 !m 6')
44
42
  expect(MVinl.context.variables[:n] && MVinl.context.variables[:m]).to be_truthy
45
43
  end
@@ -53,6 +51,17 @@ describe MVinl, '#eval' do
53
51
  end
54
52
  end
55
53
 
54
+ context 'constants' do
55
+ it 'stores a single constant' do
56
+ MVinl.eval('!N 50')
57
+ expect(MVinl::Context::CONSTANTS[:N]).to be_truthy
58
+ end
59
+ it 'evaluates a single constant' do
60
+ result = MVinl.eval('x N')
61
+ expect(result).to eq({ x: [[50], {}] })
62
+ end
63
+ end
64
+
56
65
  context 'functions' do
57
66
  it 'stores function definition with \'+\' OPER and no arguments' do
58
67
  MVinl.eval('def (f (+ 1))')
@@ -112,5 +121,20 @@ describe MVinl, '#eval_from_file' do
112
121
  line_height: 25, padding: 8
113
122
  }] } })
114
123
  end
124
+ it 'evaluates an example with variables' do
125
+ MVinl.reset
126
+ result = MVinl.eval_from_file('spec/vars.mvnl')
127
+ expect(result).to eq({ x: [[5], { fun: 10 }] })
128
+ end
129
+ it 'function respects variable change' do
130
+ MVinl.reset
131
+ result = MVinl.eval_from_file('spec/complex_vars.mvnl')
132
+ expect(result).to eq({ x: [[20], {}] })
133
+ end
134
+ it 'evaluates multiline string' do
135
+ MVinl.reset
136
+ result = MVinl.eval_from_file('spec/multiline_string.mvnl')
137
+ expect(result).to eq({ x: [['Hello, MVinl !'], {}] })
138
+ end
115
139
  end
116
140
  end
data/spec/spec_helper.rb CHANGED
@@ -1,3 +1,5 @@
1
1
  # frozen-string-literal: true
2
2
 
3
3
  $LOAD_PATH.unshift File.expand_path('lib', __dir__)
4
+
5
+ require 'mvinl'
data/spec/vars.mvnl ADDED
@@ -0,0 +1,4 @@
1
+ !a 5
2
+ def (foo (* 2 a))
3
+
4
+ x a fun: (foo)
data/syntax/mvinl.tab.rb CHANGED
@@ -8,7 +8,7 @@ require 'racc/parser.rb'
8
8
  module MVinl
9
9
  class Program < Racc::Parser
10
10
 
11
- module_eval(<<'...end mvinl.y/module_eval...', 'mvinl.y', 121)
11
+ module_eval(<<'...end mvinl.y/module_eval...', 'mvinl.y', 144)
12
12
  class MVinl::ParserError < StandardError; end
13
13
 
14
14
  private
@@ -22,16 +22,12 @@ module_eval(<<'...end mvinl.y/module_eval...', 'mvinl.y', 121)
22
22
  properties || Hash.new
23
23
  end
24
24
 
25
-
26
- def define_variable(name, value)
27
- @context.state[:in_var] = false
28
- @context.variables[name] = value
29
- value
25
+ def evaluate_const(const_name)
26
+ MVinl::Context::CONSTANTS[const_name]
30
27
  end
31
28
 
32
- def define_function(name, args, body)
33
- @context.functions[name.to_sym] = {args: args, body: body}
34
- nil
29
+ def evaluate_var(var_name)
30
+ @context.variables[var_name]
35
31
  end
36
32
 
37
33
  def evaluate_pn(operator, operands, context = {})
@@ -53,6 +49,14 @@ module_eval(<<'...end mvinl.y/module_eval...', 'mvinl.y', 121)
53
49
  new_context = function[:args].zip(operands).to_h
54
50
  # Replace symbols in body with context values
55
51
  function = replace_symbols(function[:body], new_context)
52
+ # Evaluate variables
53
+ function.map! do |e|
54
+ if e.is_a? Hash
55
+ e[:var] ? evaluate_var(e[:var]) : evaluate_const(e[:con])
56
+ else
57
+ e
58
+ end
59
+ end
56
60
  # Recursive evaluation
57
61
  evaluate_pn(function[0], function[1..], new_context)
58
62
  else
@@ -79,152 +83,166 @@ module_eval(<<'...end mvinl.y/module_eval...', 'mvinl.y', 121)
79
83
  ##### State transition tables begin ###
80
84
 
81
85
  racc_action_table = [
82
- -13, 12, -13, -13, -13, -13, 2, 16, 7, 9,
83
- 10, 25, 26, -13, 36, 16, 36, 16, -13, 11,
84
- 20, 21, 22, 24, 25, 26, 28, 28, 47, 50,
85
- 31, 16, 20, 21, 22, 24, 25, 26, 16, 28,
86
- 47, 50, 16, 16, 21, 22, 24, 25, 26, 45,
87
- 28, 47, nil, nil, 16, 21, 22, 24, 25, 26,
88
- nil, 28, 47, nil, nil, 16, 21, 22, 24, 25,
89
- 26, nil, 28, 47, nil, nil, 16, -19, 20, 21,
90
- 22, 24, 25, 26, nil, 28, 20, 21, 22, 24,
91
- 25, 26, nil, 28, 20, 21, 22, 24, 25, 26,
92
- nil, 28 ]
86
+ -16, 15, -16, -16, -16, -16, -16, 2, 19, 8,
87
+ 10, 12, 13, 29, 30, -16, 41, 19, 41, 19,
88
+ -16, 32, 14, 23, 24, 25, 26, 28, 29, 30,
89
+ 36, 32, 52, 55, 19, 19, 23, 24, 25, 26,
90
+ 28, 29, 30, 19, 32, 52, 55, 50, 19, 61,
91
+ 62, 25, 26, 28, 29, 30, 52, 32, nil, nil,
92
+ nil, 19, 61, 62, 25, 26, 28, 29, 30, nil,
93
+ 32, 52, nil, nil, 19, 61, 62, 25, 26, 28,
94
+ 29, 30, nil, 32, 52, nil, nil, 19, -22, 23,
95
+ 24, 25, 26, 28, 29, 30, nil, 32, 23, 24,
96
+ 25, 26, 28, 29, 30, nil, 32, 23, 24, 25,
97
+ 26, 28, 29, 30, nil, 32, 23, 24, 25, 26,
98
+ 28, 29, 30, nil, 32 ]
93
99
 
94
100
  racc_action_check = [
95
- 14, 2, 14, 14, 14, 14, 1, 4, 1, 1,
96
- 1, 26, 26, 14, 27, 27, 53, 53, 14, 1,
97
- 40, 40, 40, 40, 40, 40, 11, 40, 40, 40,
98
- 13, 40, 41, 41, 41, 41, 41, 41, 29, 41,
99
- 41, 41, 30, 41, 42, 42, 42, 42, 42, 38,
100
- 42, 52, nil, nil, 42, 60, 60, 60, 60, 60,
101
- nil, 60, 60, nil, nil, 60, 61, 61, 61, 61,
102
- 61, nil, 61, 61, nil, nil, 61, 32, 32, 32,
103
- 32, 32, 32, 32, nil, 32, 8, 8, 8, 8,
104
- 8, 8, nil, 8, 44, 44, 44, 44, 44, 44,
105
- nil, 44 ]
101
+ 17, 2, 17, 17, 17, 17, 17, 1, 4, 1,
102
+ 1, 1, 1, 30, 30, 17, 31, 31, 58, 58,
103
+ 17, 14, 1, 45, 45, 45, 45, 45, 45, 45,
104
+ 16, 45, 45, 45, 34, 45, 46, 46, 46, 46,
105
+ 46, 46, 46, 35, 46, 46, 46, 43, 46, 47,
106
+ 47, 47, 47, 47, 47, 47, 57, 47, nil, nil,
107
+ nil, 47, 67, 67, 67, 67, 67, 67, 67, nil,
108
+ 67, 67, nil, nil, 67, 68, 68, 68, 68, 68,
109
+ 68, 68, nil, 68, 68, nil, nil, 68, 37, 37,
110
+ 37, 37, 37, 37, 37, 37, nil, 37, 9, 9,
111
+ 9, 9, 9, 9, 9, nil, 9, 11, 11, 11,
112
+ 11, 11, 11, 11, nil, 11, 49, 49, 49, 49,
113
+ 49, 49, 49, nil, 49 ]
106
114
 
107
115
  racc_action_pointer = [
108
- nil, 6, 1, nil, -11, nil, nil, nil, 79, nil,
109
- nil, 12, nil, 25, 0, nil, nil, nil, nil, nil,
110
- nil, nil, nil, nil, nil, nil, 0, -3, nil, 20,
111
- 24, nil, 71, nil, nil, nil, nil, nil, 43, nil,
112
- 13, 25, 36, nil, 87, nil, nil, nil, nil, nil,
113
- nil, nil, 36, -1, nil, nil, nil, nil, nil, nil,
114
- 47, 58, nil, nil, nil ]
116
+ nil, 7, 1, nil, -12, nil, nil, nil, nil, 90,
117
+ nil, 99, nil, nil, 5, nil, 24, 0, nil, nil,
118
+ nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
119
+ 0, -3, nil, nil, 14, 23, nil, 81, nil, nil,
120
+ nil, nil, nil, 40, nil, 15, 28, 41, nil, 108,
121
+ nil, nil, nil, nil, nil, nil, nil, 39, -1, nil,
122
+ nil, nil, nil, nil, nil, nil, nil, 54, 67, nil,
123
+ nil, nil ]
115
124
 
116
125
  racc_action_default = [
117
- -1, -10, -49, -2, -3, -4, -5, -6, -49, -8,
118
- -10, -49, 65, -11, -17, -16, -48, -7, -23, -24,
119
- -25, -26, -27, -28, -29, -30, -49, -49, -37, -9,
120
- -49, -12, -14, -31, -43, -43, -47, -39, -15, -18,
121
- -49, -49, -49, -20, -49, -22, -35, -38, -44, -45,
122
- -46, -36, -42, -49, -40, -41, -21, -32, -39, -39,
123
- -49, -49, -33, -42, -34 ]
126
+ -1, -13, -55, -2, -3, -4, -5, -6, -7, -55,
127
+ -9, -55, -11, -13, -55, 72, -14, -20, -19, -54,
128
+ -8, -26, -27, -28, -29, -30, -31, -32, -33, -34,
129
+ -55, -55, -41, -10, -12, -55, -15, -17, -35, -49,
130
+ -49, -53, -43, -18, -21, -55, -55, -55, -23, -55,
131
+ -25, -39, -42, -50, -51, -52, -40, -48, -55, -44,
132
+ -45, -46, -47, -24, -36, -43, -43, -55, -55, -37,
133
+ -48, -38 ]
124
134
 
125
135
  racc_goto_table = [
126
- 30, 42, 15, 1, 35, 17, 4, 40, 41, 3,
127
- 5, 6, 46, 51, 8, 29, 55, 32, 38, 43,
128
- 44, 33, 60, 61, 57, 34, 52, 15, 37, 39,
129
- 59, 53, 62, 64, 55, 55, nil, nil, 49, 49,
130
- nil, 56, nil, nil, nil, nil, nil, nil, nil, 53,
131
- 53, 58 ]
136
+ 18, 40, 35, 60, 20, 4, 33, 45, 46, 1,
137
+ 47, 3, 5, 6, 51, 56, 7, 34, 9, 11,
138
+ 37, 43, 48, 60, 60, 49, 64, 39, 66, 38,
139
+ 18, 42, 44, 67, 68, 58, 69, 71, 57, nil,
140
+ nil, 54, 54, nil, 63, nil, nil, nil, nil, nil,
141
+ nil, nil, nil, nil, 65, 58, 58 ]
132
142
 
133
143
  racc_goto_check = [
134
- 18, 19, 12, 1, 22, 7, 3, 23, 23, 2,
135
- 4, 5, 21, 21, 6, 3, 15, 10, 11, 13,
136
- 14, 17, 19, 19, 21, 12, 20, 12, 12, 7,
137
- 22, 18, 21, 21, 15, 15, nil, nil, 12, 12,
138
- nil, 7, nil, nil, nil, nil, nil, nil, nil, 18,
139
- 18, 12 ]
144
+ 14, 24, 20, 17, 8, 3, 8, 25, 25, 1,
145
+ 21, 2, 4, 5, 23, 23, 6, 3, 7, 9,
146
+ 12, 13, 15, 17, 17, 16, 23, 14, 24, 19,
147
+ 14, 14, 8, 21, 21, 20, 23, 23, 22, nil,
148
+ nil, 14, 14, nil, 8, nil, nil, nil, nil, nil,
149
+ nil, nil, nil, nil, 14, 20, 20 ]
140
150
 
141
151
  racc_goto_pointer = [
142
- nil, 3, 8, 5, 9, 10, 13, -3, nil, nil,
143
- 3, -14, -2, -19, -18, -26, nil, -5, -11, -36,
144
- -16, -28, -23, -27 ]
152
+ nil, 9, 10, 4, 11, 12, 15, 17, -5, 18,
153
+ nil, nil, 3, -16, -4, -21, -18, -44, nil, -1,
154
+ -12, -32, -9, -31, -30, -32 ]
145
155
 
146
156
  racc_goto_default = [
147
- nil, nil, nil, nil, nil, nil, nil, 48, 13, 14,
148
- nil, nil, 54, nil, nil, 18, 19, 23, 27, nil,
149
- 63, nil, nil, nil ]
157
+ nil, nil, nil, nil, nil, nil, nil, nil, 53, nil,
158
+ 16, 17, nil, nil, 59, nil, nil, 21, 22, 27,
159
+ 31, nil, 70, nil, nil, nil ]
150
160
 
151
161
  racc_reduce_table = [
152
162
  0, 0, :racc_error,
153
- 0, 20, :_reduce_1,
154
- 2, 20, :_reduce_2,
155
- 2, 20, :_reduce_3,
156
- 2, 20, :_reduce_4,
157
- 2, 20, :_reduce_5,
158
- 2, 20, :_reduce_6,
159
- 2, 23, :_reduce_7,
160
- 1, 25, :_reduce_8,
161
- 2, 21, :_reduce_9,
162
- 0, 22, :_reduce_10,
163
- 2, 22, :_reduce_11,
164
- 3, 22, :_reduce_12,
165
- 1, 27, :_reduce_13,
166
- 2, 27, :_reduce_14,
167
- 3, 27, :_reduce_15,
168
- 1, 28, :_reduce_16,
169
- 0, 29, :_reduce_17,
170
- 2, 29, :_reduce_18,
171
- 0, 30, :_reduce_19,
172
- 2, 30, :_reduce_20,
173
- 2, 32, :_reduce_21,
174
- 1, 33, :_reduce_22,
175
- 1, 26, :_reduce_23,
176
- 1, 26, :_reduce_24,
177
- 1, 26, :_reduce_25,
178
- 1, 34, :_reduce_26,
179
- 1, 34, :_reduce_27,
180
- 1, 34, :_reduce_28,
181
- 1, 34, :_reduce_29,
182
- 1, 36, :_reduce_30,
183
- 2, 36, :_reduce_31,
184
- 6, 24, :_reduce_32,
185
- 4, 39, :_reduce_33,
186
- 4, 39, :_reduce_34,
187
- 4, 35, :_reduce_35,
188
- 4, 35, :_reduce_36,
189
- 1, 37, :_reduce_37,
190
- 1, 40, :_reduce_38,
191
- 0, 38, :_reduce_39,
192
- 2, 38, :_reduce_40,
193
- 2, 38, :_reduce_41,
194
- 2, 38, :_reduce_42,
163
+ 0, 22, :_reduce_1,
164
+ 2, 22, :_reduce_2,
165
+ 2, 22, :_reduce_3,
166
+ 2, 22, :_reduce_4,
167
+ 2, 22, :_reduce_5,
168
+ 2, 22, :_reduce_6,
169
+ 2, 22, :_reduce_7,
170
+ 2, 26, :_reduce_8,
171
+ 1, 28, :_reduce_9,
172
+ 2, 25, :_reduce_10,
173
+ 1, 30, :_reduce_11,
174
+ 2, 23, :_reduce_12,
175
+ 0, 24, :_reduce_13,
176
+ 2, 24, :_reduce_14,
177
+ 3, 24, :_reduce_15,
178
+ 1, 31, :_reduce_16,
179
+ 2, 31, :_reduce_17,
180
+ 3, 31, :_reduce_18,
181
+ 1, 32, :_reduce_19,
182
+ 0, 33, :_reduce_20,
183
+ 2, 33, :_reduce_21,
184
+ 0, 34, :_reduce_22,
185
+ 2, 34, :_reduce_23,
186
+ 2, 36, :_reduce_24,
187
+ 1, 37, :_reduce_25,
188
+ 1, 29, :_reduce_26,
189
+ 1, 29, :_reduce_27,
190
+ 1, 29, :_reduce_28,
191
+ 1, 29, :_reduce_29,
192
+ 1, 38, :_reduce_30,
193
+ 1, 38, :_reduce_31,
194
+ 1, 38, :_reduce_32,
195
+ 1, 38, :_reduce_33,
196
+ 1, 40, :_reduce_34,
197
+ 2, 40, :_reduce_35,
198
+ 6, 27, :_reduce_36,
199
+ 4, 43, :_reduce_37,
200
+ 4, 43, :_reduce_38,
201
+ 4, 39, :_reduce_39,
202
+ 4, 39, :_reduce_40,
203
+ 1, 41, :_reduce_41,
204
+ 1, 44, :_reduce_42,
195
205
  0, 42, :_reduce_43,
196
206
  2, 42, :_reduce_44,
197
207
  2, 42, :_reduce_45,
198
208
  2, 42, :_reduce_46,
199
- 1, 41, :_reduce_47,
200
- 1, 31, :_reduce_48 ]
209
+ 2, 42, :_reduce_47,
210
+ 2, 42, :_reduce_48,
211
+ 0, 46, :_reduce_49,
212
+ 2, 46, :_reduce_50,
213
+ 2, 46, :_reduce_51,
214
+ 2, 46, :_reduce_52,
215
+ 1, 45, :_reduce_53,
216
+ 1, 35, :_reduce_54 ]
201
217
 
202
- racc_reduce_n = 49
218
+ racc_reduce_n = 55
203
219
 
204
- racc_shift_n = 65
220
+ racc_shift_n = 72
205
221
 
206
222
  racc_token_table = {
207
223
  false => 0,
208
224
  :error => 1,
209
225
  :EOS => 2,
210
226
  :VARIABLE => 3,
211
- :GROUP => 4,
212
- :END_TAG => 5,
213
- :KEYWORD_ARG => 6,
214
- :VARIABLE_CALL => 7,
215
- :NUMBER => 8,
216
- :FLOAT => 9,
217
- :SYMBOL => 10,
218
- :STRING => 11,
219
- :MULTILINE_STRING => 12,
220
- :DEF => 13,
221
- :OPEN_PAREN => 14,
222
- :CLOSE_PAREN => 15,
223
- :polish_notation => 16,
224
- :OPER => 17,
225
- :ID => 18 }
226
-
227
- racc_nt_base = 19
227
+ :CONSTANT => 4,
228
+ :GROUP => 5,
229
+ :END_TAG => 6,
230
+ :KEYWORD_ARG => 7,
231
+ :CONSTANT_CALL => 8,
232
+ :VARIABLE_CALL => 9,
233
+ :NUMBER => 10,
234
+ :FLOAT => 11,
235
+ :SYMBOL => 12,
236
+ :STRING => 13,
237
+ :MULTILINE_STRING => 14,
238
+ :DEF => 15,
239
+ :OPEN_PAREN => 16,
240
+ :CLOSE_PAREN => 17,
241
+ :polish_notation => 18,
242
+ :OPER => 19,
243
+ :ID => 20 }
244
+
245
+ racc_nt_base = 21
228
246
 
229
247
  racc_use_result_var = false
230
248
 
@@ -250,9 +268,11 @@ Racc_token_to_s_table = [
250
268
  "error",
251
269
  "EOS",
252
270
  "VARIABLE",
271
+ "CONSTANT",
253
272
  "GROUP",
254
273
  "END_TAG",
255
274
  "KEYWORD_ARG",
275
+ "CONSTANT_CALL",
256
276
  "VARIABLE_CALL",
257
277
  "NUMBER",
258
278
  "FLOAT",
@@ -269,10 +289,12 @@ Racc_token_to_s_table = [
269
289
  "program",
270
290
  "group",
271
291
  "properties",
292
+ "constant_def",
272
293
  "variable_def",
273
294
  "function_def",
274
295
  "var_def_name",
275
296
  "super_value",
297
+ "const_def_name",
276
298
  "property",
277
299
  "prop_id",
278
300
  "positional_args",
@@ -333,94 +355,121 @@ module_eval(<<'.,.,', 'mvinl.y', 17)
333
355
  end
334
356
  .,.,
335
357
 
336
- module_eval(<<'.,.,', 'mvinl.y', 20)
358
+ module_eval(<<'.,.,', 'mvinl.y', 18)
337
359
  def _reduce_7(val, _values)
338
- define_variable(val[0], val[1])
360
+ val[0]
339
361
  end
340
362
  .,.,
341
363
 
342
364
  module_eval(<<'.,.,', 'mvinl.y', 23)
343
365
  def _reduce_8(val, _values)
344
- @context.state[:in_var] = true; val[0].to_sym
366
+ @context.define_variable(val[0], val[1]) ||
367
+ raise(MVinl::ParserError, "Trying to define a reserved word '#{val[0]}' as a variable")
368
+
345
369
  end
346
370
  .,.,
347
371
 
348
- module_eval(<<'.,.,', 'mvinl.y', 26)
372
+ module_eval(<<'.,.,', 'mvinl.y', 28)
349
373
  def _reduce_9(val, _values)
350
- {val[0].to_sym => create_group(val[1])}
374
+ @context.state[:in_var] = true; val[0].to_sym
351
375
  end
352
376
  .,.,
353
377
 
354
- module_eval(<<'.,.,', 'mvinl.y', 29)
378
+ module_eval(<<'.,.,', 'mvinl.y', 33)
355
379
  def _reduce_10(val, _values)
356
- Hash.new
380
+ if (res = @context.define_constant(val[0], val[1])) == nil
381
+ raise(MVinl::ParserError, "Trying to define a reserved word '#{val[0]}' as a constant")
382
+ elsif (res == false)
383
+ raise(MVinl::ParserError, "Can't overwrite a constant #{val[0]}")
384
+ else
385
+ res
386
+ end
387
+
357
388
  end
358
389
  .,.,
359
390
 
360
- module_eval(<<'.,.,', 'mvinl.y', 30)
391
+ module_eval(<<'.,.,', 'mvinl.y', 43)
361
392
  def _reduce_11(val, _values)
362
- val[0].merge(val[1])
393
+ @context.state[:in_var] = true; val[0].to_sym
363
394
  end
364
395
  .,.,
365
396
 
366
- module_eval(<<'.,.,', 'mvinl.y', 31)
397
+ module_eval(<<'.,.,', 'mvinl.y', 46)
367
398
  def _reduce_12(val, _values)
368
- val[0].merge(val[1])
399
+ {val[0].to_sym => create_group(val[1])}
369
400
  end
370
401
  .,.,
371
402
 
372
- module_eval(<<'.,.,', 'mvinl.y', 34)
403
+ module_eval(<<'.,.,', 'mvinl.y', 49)
373
404
  def _reduce_13(val, _values)
374
- create_property(val[0])
405
+ Hash.new
375
406
  end
376
407
  .,.,
377
408
 
378
- module_eval(<<'.,.,', 'mvinl.y', 35)
409
+ module_eval(<<'.,.,', 'mvinl.y', 50)
379
410
  def _reduce_14(val, _values)
380
- create_property(val[0], val[1])
411
+ val[0].merge(val[1])
381
412
  end
382
413
  .,.,
383
414
 
384
- module_eval(<<'.,.,', 'mvinl.y', 36)
415
+ module_eval(<<'.,.,', 'mvinl.y', 51)
385
416
  def _reduce_15(val, _values)
386
- create_property(val[0], val[1], val[2])
417
+ val[0].merge(val[1])
387
418
  end
388
419
  .,.,
389
420
 
390
- module_eval(<<'.,.,', 'mvinl.y', 39)
421
+ module_eval(<<'.,.,', 'mvinl.y', 54)
391
422
  def _reduce_16(val, _values)
392
- @context.state[:in_prop] = true; val[0]
423
+ create_property(val[0])
393
424
  end
394
425
  .,.,
395
426
 
396
- module_eval(<<'.,.,', 'mvinl.y', 42)
427
+ module_eval(<<'.,.,', 'mvinl.y', 55)
397
428
  def _reduce_17(val, _values)
398
- Array.new
429
+ create_property(val[0], val[1])
399
430
  end
400
431
  .,.,
401
432
 
402
- module_eval(<<'.,.,', 'mvinl.y', 43)
433
+ module_eval(<<'.,.,', 'mvinl.y', 56)
403
434
  def _reduce_18(val, _values)
404
- val[0] << val[1]
435
+ create_property(val[0], val[1], val[2])
405
436
  end
406
437
  .,.,
407
438
 
408
- module_eval(<<'.,.,', 'mvinl.y', 46)
439
+ module_eval(<<'.,.,', 'mvinl.y', 59)
409
440
  def _reduce_19(val, _values)
410
- Hash.new
441
+ @context.state[:in_prop] = true; val[0]
411
442
  end
412
443
  .,.,
413
444
 
414
- module_eval(<<'.,.,', 'mvinl.y', 49)
445
+ module_eval(<<'.,.,', 'mvinl.y', 62)
415
446
  def _reduce_20(val, _values)
447
+ Array.new
448
+ end
449
+ .,.,
450
+
451
+ module_eval(<<'.,.,', 'mvinl.y', 63)
452
+ def _reduce_21(val, _values)
453
+ val[0] << val[1]
454
+ end
455
+ .,.,
456
+
457
+ module_eval(<<'.,.,', 'mvinl.y', 66)
458
+ def _reduce_22(val, _values)
459
+ Hash.new
460
+ end
461
+ .,.,
462
+
463
+ module_eval(<<'.,.,', 'mvinl.y', 69)
464
+ def _reduce_23(val, _values)
416
465
  @context.state[:keyword_arg_depth] = 0
417
466
  val[0].merge(val[1])
418
467
 
419
468
  end
420
469
  .,.,
421
470
 
422
- module_eval(<<'.,.,', 'mvinl.y', 56)
423
- def _reduce_21(val, _values)
471
+ module_eval(<<'.,.,', 'mvinl.y', 76)
472
+ def _reduce_24(val, _values)
424
473
  @context.state[:in_keyword_arg] = false
425
474
  @context.state[:keyword_arg_depth] += 1
426
475
  {val[0].to_sym => val[1]}
@@ -428,165 +477,183 @@ module_eval(<<'.,.,', 'mvinl.y', 56)
428
477
  end
429
478
  .,.,
430
479
 
431
- module_eval(<<'.,.,', 'mvinl.y', 62)
432
- def _reduce_22(val, _values)
480
+ module_eval(<<'.,.,', 'mvinl.y', 82)
481
+ def _reduce_25(val, _values)
433
482
  @context.state[:in_keyword_arg] = true; val[0]
434
483
  end
435
484
  .,.,
436
485
 
437
- module_eval(<<'.,.,', 'mvinl.y', 65)
438
- def _reduce_23(val, _values)
486
+ module_eval(<<'.,.,', 'mvinl.y', 85)
487
+ def _reduce_26(val, _values)
439
488
  val[0]
440
489
  end
441
490
  .,.,
442
491
 
443
- module_eval(<<'.,.,', 'mvinl.y', 66)
444
- def _reduce_24(val, _values)
492
+ module_eval(<<'.,.,', 'mvinl.y', 86)
493
+ def _reduce_27(val, _values)
445
494
  val[0]
446
495
  end
447
496
  .,.,
448
497
 
449
- module_eval(<<'.,.,', 'mvinl.y', 67)
450
- def _reduce_25(val, _values)
451
- val[0]
498
+ module_eval(<<'.,.,', 'mvinl.y', 87)
499
+ def _reduce_28(val, _values)
500
+ MVinl::Context::CONSTANTS[val[0]]
452
501
  end
453
502
  .,.,
454
503
 
455
- module_eval(<<'.,.,', 'mvinl.y', 70)
456
- def _reduce_26(val, _values)
504
+ module_eval(<<'.,.,', 'mvinl.y', 88)
505
+ def _reduce_29(val, _values)
506
+ @context.variables[val[0]]
507
+ end
508
+ .,.,
509
+
510
+ module_eval(<<'.,.,', 'mvinl.y', 91)
511
+ def _reduce_30(val, _values)
457
512
  val[0].to_i
458
513
  end
459
514
  .,.,
460
515
 
461
- module_eval(<<'.,.,', 'mvinl.y', 71)
462
- def _reduce_27(val, _values)
516
+ module_eval(<<'.,.,', 'mvinl.y', 92)
517
+ def _reduce_31(val, _values)
463
518
  val[0].to_f
464
519
  end
465
520
  .,.,
466
521
 
467
- module_eval(<<'.,.,', 'mvinl.y', 72)
468
- def _reduce_28(val, _values)
522
+ module_eval(<<'.,.,', 'mvinl.y', 93)
523
+ def _reduce_32(val, _values)
469
524
  val[0]
470
525
  end
471
526
  .,.,
472
527
 
473
- module_eval(<<'.,.,', 'mvinl.y', 73)
474
- def _reduce_29(val, _values)
528
+ module_eval(<<'.,.,', 'mvinl.y', 94)
529
+ def _reduce_33(val, _values)
475
530
  val[0].to_sym
476
531
  end
477
532
  .,.,
478
533
 
479
- module_eval(<<'.,.,', 'mvinl.y', 76)
480
- def _reduce_30(val, _values)
534
+ module_eval(<<'.,.,', 'mvinl.y', 97)
535
+ def _reduce_34(val, _values)
481
536
  val[0]
482
537
  end
483
538
  .,.,
484
539
 
485
- module_eval(<<'.,.,', 'mvinl.y', 77)
486
- def _reduce_31(val, _values)
540
+ module_eval(<<'.,.,', 'mvinl.y', 98)
541
+ def _reduce_35(val, _values)
487
542
  "#{val[0]} #{val[1]}"
488
543
  end
489
544
  .,.,
490
545
 
491
- module_eval(<<'.,.,', 'mvinl.y', 82)
492
- def _reduce_32(val, _values)
493
- define_function(val[2], val[3], val[4])
546
+ module_eval(<<'.,.,', 'mvinl.y', 103)
547
+ def _reduce_36(val, _values)
548
+ @context.define_function(val[2], val[3], val[4])
494
549
 
495
550
  end
496
551
  .,.,
497
552
 
498
- module_eval(<<'.,.,', 'mvinl.y', 86)
499
- def _reduce_33(val, _values)
553
+ module_eval(<<'.,.,', 'mvinl.y', 107)
554
+ def _reduce_37(val, _values)
500
555
  [val[1], *val[2]]
501
556
  end
502
557
  .,.,
503
558
 
504
- module_eval(<<'.,.,', 'mvinl.y', 87)
505
- def _reduce_34(val, _values)
559
+ module_eval(<<'.,.,', 'mvinl.y', 108)
560
+ def _reduce_38(val, _values)
506
561
  [val[1], *val[2]]
507
562
  end
508
563
  .,.,
509
564
 
510
- module_eval(<<'.,.,', 'mvinl.y', 90)
511
- def _reduce_35(val, _values)
565
+ module_eval(<<'.,.,', 'mvinl.y', 111)
566
+ def _reduce_39(val, _values)
512
567
  evaluate_pn(val[1], val[2])
513
568
  end
514
569
  .,.,
515
570
 
516
- module_eval(<<'.,.,', 'mvinl.y', 91)
517
- def _reduce_36(val, _values)
571
+ module_eval(<<'.,.,', 'mvinl.y', 112)
572
+ def _reduce_40(val, _values)
518
573
  evaluate_pn(val[1], val[2])
519
574
  end
520
575
  .,.,
521
576
 
522
- module_eval(<<'.,.,', 'mvinl.y', 94)
523
- def _reduce_37(val, _values)
577
+ module_eval(<<'.,.,', 'mvinl.y', 115)
578
+ def _reduce_41(val, _values)
524
579
  @context.state[:depth] += 1
525
580
  end
526
581
  .,.,
527
582
 
528
- module_eval(<<'.,.,', 'mvinl.y', 97)
529
- def _reduce_38(val, _values)
583
+ module_eval(<<'.,.,', 'mvinl.y', 118)
584
+ def _reduce_42(val, _values)
530
585
  @context.state[:depth] -= 1
531
586
  end
532
587
  .,.,
533
588
 
534
- module_eval(<<'.,.,', 'mvinl.y', 100)
535
- def _reduce_39(val, _values)
589
+ module_eval(<<'.,.,', 'mvinl.y', 121)
590
+ def _reduce_43(val, _values)
536
591
  Array.new
537
592
  end
538
593
  .,.,
539
594
 
540
- module_eval(<<'.,.,', 'mvinl.y', 101)
541
- def _reduce_40(val, _values)
595
+ module_eval(<<'.,.,', 'mvinl.y', 122)
596
+ def _reduce_44(val, _values)
542
597
  val[0] << val[1]
543
598
  end
544
599
  .,.,
545
600
 
546
- module_eval(<<'.,.,', 'mvinl.y', 102)
547
- def _reduce_41(val, _values)
601
+ module_eval(<<'.,.,', 'mvinl.y', 123)
602
+ def _reduce_45(val, _values)
548
603
  val[0] << val[1]
549
604
  end
550
605
  .,.,
551
606
 
552
- module_eval(<<'.,.,', 'mvinl.y', 103)
553
- def _reduce_42(val, _values)
607
+ module_eval(<<'.,.,', 'mvinl.y', 124)
608
+ def _reduce_46(val, _values)
609
+ val[0] << { con: val[1] }
610
+ end
611
+ .,.,
612
+
613
+ module_eval(<<'.,.,', 'mvinl.y', 125)
614
+ def _reduce_47(val, _values)
615
+ val[0] << { var: val[1] }
616
+ end
617
+ .,.,
618
+
619
+ module_eval(<<'.,.,', 'mvinl.y', 126)
620
+ def _reduce_48(val, _values)
554
621
  val[0] << val[1]
555
622
  end
556
623
  .,.,
557
624
 
558
- module_eval(<<'.,.,', 'mvinl.y', 106)
559
- def _reduce_43(val, _values)
625
+ module_eval(<<'.,.,', 'mvinl.y', 129)
626
+ def _reduce_49(val, _values)
560
627
  Array.new
561
628
  end
562
629
  .,.,
563
630
 
564
- module_eval(<<'.,.,', 'mvinl.y', 107)
565
- def _reduce_44(val, _values)
631
+ module_eval(<<'.,.,', 'mvinl.y', 130)
632
+ def _reduce_50(val, _values)
566
633
  val[0] << val[1]
567
634
  end
568
635
  .,.,
569
636
 
570
- module_eval(<<'.,.,', 'mvinl.y', 108)
571
- def _reduce_45(val, _values)
637
+ module_eval(<<'.,.,', 'mvinl.y', 131)
638
+ def _reduce_51(val, _values)
572
639
  val[0] << val[1]
573
640
  end
574
641
  .,.,
575
642
 
576
- module_eval(<<'.,.,', 'mvinl.y', 109)
577
- def _reduce_46(val, _values)
643
+ module_eval(<<'.,.,', 'mvinl.y', 132)
644
+ def _reduce_52(val, _values)
578
645
  val[0] << val[1]
579
646
  end
580
647
  .,.,
581
648
 
582
- module_eval(<<'.,.,', 'mvinl.y', 112)
583
- def _reduce_47(val, _values)
649
+ module_eval(<<'.,.,', 'mvinl.y', 135)
650
+ def _reduce_53(val, _values)
584
651
  val[0].to_sym
585
652
  end
586
653
  .,.,
587
654
 
588
- module_eval(<<'.,.,', 'mvinl.y', 115)
589
- def _reduce_48(val, _values)
655
+ module_eval(<<'.,.,', 'mvinl.y', 138)
656
+ def _reduce_54(val, _values)
590
657
  val[0].to_sym
591
658
  end
592
659
  .,.,
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mvinl
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.1.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - siery
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-12-10 00:00:00.000000000 Z
11
+ date: 2024-12-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: pp
@@ -47,9 +47,12 @@ files:
47
47
  - lib/mvinl/parser.rb
48
48
  - mvinl.gemspec
49
49
  - rakelib/build.rake
50
+ - spec/complex_vars.mvnl
51
+ - spec/multiline_string.mvnl
50
52
  - spec/program_spec.rb
51
53
  - spec/spec_helper.rb
52
54
  - spec/stack.mvnl
55
+ - spec/vars.mvnl
53
56
  - syntax/mvinl.tab.rb
54
57
  homepage: https://rubygems.org/gems/mvinl
55
58
  licenses: