mvinl 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 +7 -0
- data/.gitignore +26 -0
- data/.ruby-version +1 -0
- data/Gemfile +8 -0
- data/LICENSE +21 -0
- data/README.md +60 -0
- data/Rakefile +5 -0
- data/bin/imvnl +65 -0
- data/edit/mvinl.vim +63 -0
- data/lib/mvinl/info.rb +12 -0
- data/lib/mvinl/lexer.rb +155 -0
- data/lib/mvinl/parser.rb +43 -0
- data/lib/mvinl.rb +37 -0
- data/mvinl.gemspec +33 -0
- data/rakelib/build.rake +8 -0
- data/spec/stack.mvnl +21 -0
- data/syntax/mvinl.tab.rb +519 -0
- metadata +79 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: f891e7bb1683b84d918155e32b06fdf03ae4d00791676e4b1dc467c30d495b90
|
4
|
+
data.tar.gz: c96e8a9930ed532580014843594d70d3fb025089fdd06708e9440b5316c2a772
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: febf482245e910fe310efae6a5aaaa115769830475678ba8b0e8b0d65dee6b0b4e22f5a4d9d5e5236f5a8e35e0125f55d406a155c6e2b3e4441ced8f7dfe05de
|
7
|
+
data.tar.gz: fb604a7c640da0406c0d0a1190ba0a684491728cd1b9b666da5e870bd754b50d8ebde6ad5a2e3dfea0aecab98e98fc60e7dfbb3d35f94526d5294e981ef91bb1
|
data/.gitignore
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
*
|
2
|
+
!*/
|
3
|
+
!.gitignore
|
4
|
+
|
5
|
+
# Package
|
6
|
+
!README.md
|
7
|
+
!LICENSE
|
8
|
+
!.ruby-version
|
9
|
+
!Gemfile
|
10
|
+
!mvinl.gemspec
|
11
|
+
!Rakefile
|
12
|
+
!rakelib/[a-z]*.rake
|
13
|
+
!edit/mvinl.vim
|
14
|
+
|
15
|
+
# Executables
|
16
|
+
!bin/imvnl
|
17
|
+
|
18
|
+
# Library code
|
19
|
+
!lib/mvinl.rb
|
20
|
+
!lib/mvinl/[a-z]*.rb
|
21
|
+
|
22
|
+
!syntax/mvinl.y
|
23
|
+
|
24
|
+
# Spec
|
25
|
+
!spec/[a-z]*.mvnl
|
26
|
+
!spec/[a-z]*.rb
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
3.2.2
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2024 Daniel Sierpiński
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
# MVinl
|
2
|
+
|
3
|
+
A mini stack configuration language.
|
4
|
+
|
5
|
+
*Mini Vinl is not Lisp*
|
6
|
+
|
7
|
+
## Install
|
8
|
+
|
9
|
+
MVinl is packaged as gem. To install it from RubyGems.org go
|
10
|
+
|
11
|
+
```
|
12
|
+
gem install mvinl
|
13
|
+
```
|
14
|
+
|
15
|
+
or build and install it from this repo if you have it downloaded
|
16
|
+
|
17
|
+
```
|
18
|
+
gem build
|
19
|
+
gem install ./mvinl-0.1.0.gem
|
20
|
+
```
|
21
|
+
|
22
|
+
## Usage
|
23
|
+
|
24
|
+
Use `MVinl.eval` or `MVinl.eval_from_file` to evaluate mvinl code.
|
25
|
+
|
26
|
+
`imvnl` is an interactive shell for mvinl. It's not really how the language
|
27
|
+
suppose to be used but it's useful for quckly testing expressions.
|
28
|
+
|
29
|
+
Vinl execution returns a hash similar to YAML or JSON. The point is to create a
|
30
|
+
configuration structure to initiate objects in an application, like a game
|
31
|
+
engine.
|
32
|
+
|
33
|
+
The main elements that construct the resulting structure are groups and
|
34
|
+
properties. Groups typically sort objects into data categories, such as states.
|
35
|
+
Properties can be thought of as object constructors.
|
36
|
+
|
37
|
+
**Example:**
|
38
|
+
|
39
|
+
``` mvinl
|
40
|
+
def (center x (/ x 2))
|
41
|
+
|
42
|
+
@start
|
43
|
+
SplashScreen 'path/to/image'.
|
44
|
+
|
45
|
+
@second
|
46
|
+
Buttom (center 1920)
|
47
|
+
(center 1080)
|
48
|
+
"Hello, MVinl!"
|
49
|
+
font_size: 21 # END_TAG is optional
|
50
|
+
```
|
51
|
+
|
52
|
+
## Contribute
|
53
|
+
|
54
|
+
I happily accept suggestions and changes. Please leave bug rapports
|
55
|
+
[here](https://github.com/513ry/mvinl/issues).
|
56
|
+
|
57
|
+
## License
|
58
|
+
|
59
|
+
MVinl is a free software distributed under MIT license. Read LICENSE file for
|
60
|
+
legal notice.
|
data/Rakefile
ADDED
data/bin/imvnl
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen-string-literal: true
|
3
|
+
|
4
|
+
=begin engine.rb
|
5
|
+
Copyright (c) 2018, 2024, Daniel Sierpiński All rights reserved.
|
6
|
+
|
7
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
8
|
+
of this software and associated documentation files (the "Software"), to deal
|
9
|
+
in the Software without restriction, including without limitation the rights
|
10
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
11
|
+
copies of the Software, and to permit persons to whom the Software is
|
12
|
+
furnished to do so, subject to the following conditions:
|
13
|
+
|
14
|
+
The above copyright notice and this permission notice shall be included in
|
15
|
+
all copies or substantial portions of the Software.
|
16
|
+
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
18
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
19
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
20
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
21
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
22
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
23
|
+
THE SOFTWARE.
|
24
|
+
=end
|
25
|
+
|
26
|
+
require 'readline'
|
27
|
+
require 'pry'
|
28
|
+
require 'mvinl/lexer'
|
29
|
+
require 'mvinl/parser'
|
30
|
+
require 'mvinl/info'
|
31
|
+
|
32
|
+
PSL = "mvnl(#{MVinl::Version})".freeze
|
33
|
+
PS1 = "#{PSL}>".freeze
|
34
|
+
|
35
|
+
module MVinl::REPL
|
36
|
+
LEXER = MVinl::Lexer.new('')
|
37
|
+
PARSER = MVinl::Parser.new(LEXER)
|
38
|
+
|
39
|
+
def self.run
|
40
|
+
while (input = Readline.readline("#{PS1} ", true))
|
41
|
+
Readline::HISTORY.pop if input.strip.empty?
|
42
|
+
|
43
|
+
if input == '^' || input == 'exit'
|
44
|
+
PARSER.finalize!
|
45
|
+
break if PARSER.parsing_done?
|
46
|
+
else
|
47
|
+
LEXER.feed input
|
48
|
+
end
|
49
|
+
|
50
|
+
begin
|
51
|
+
out = PARSER.parse
|
52
|
+
print '=> '
|
53
|
+
pp out
|
54
|
+
rescue MVinl::LexerError => e
|
55
|
+
warn e.message
|
56
|
+
rescue MVinl::ParserError => e
|
57
|
+
warn e.message
|
58
|
+
rescue Racc::ParseError => e
|
59
|
+
warn e.message
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
MVinl::REPL.run
|
data/edit/mvinl.vim
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
" Vim syntax file
|
2
|
+
" Language: MVinl
|
3
|
+
" Maintainer: Daniel Sierpinski
|
4
|
+
" Last Change: Dec 04, 2024
|
5
|
+
" Version: 1
|
6
|
+
"
|
7
|
+
" Thanks to the authors of lisp.vim
|
8
|
+
" ---------------------------------------------------------------------
|
9
|
+
autocmd BufNewFile,BufRead *.mvnl set filetype=mvinl
|
10
|
+
|
11
|
+
let s:id = "[a-zA-Z_][a-zA-Z0-9_]*"
|
12
|
+
|
13
|
+
syn keyword mvinlKeyword style as def
|
14
|
+
execute 'syn match mvinlIdentifier "' . s:id . '"'
|
15
|
+
syn match mvinlNumber "[0-9]\+"
|
16
|
+
execute 'syn match mvinlSymbol ":' . s:id . '"'
|
17
|
+
syn match mvinlString "\"((?:\\.|[^\"\\])*)\""
|
18
|
+
execute 'syn match mvinlKeywordArg "' . s:id . ':"'
|
19
|
+
execute 'syn match mvinlGroup "@' . s:id . '"'
|
20
|
+
syn match mvinlComment "#.*\n"
|
21
|
+
syn match mvinlOper "[+\-*/%]" contained
|
22
|
+
|
23
|
+
unlet s:id
|
24
|
+
|
25
|
+
syn cluster mvinlValue contains=mvnilString,mvinlNumber,mvinlSymbol
|
26
|
+
syn cluster mvinlLambda contains=@mvinlValue,mvinlIdentifier,mvinlOper
|
27
|
+
|
28
|
+
" ---------------------------------------------------------------------
|
29
|
+
" Match polish notation:
|
30
|
+
syn region mvinlParen0 matchgroup=hlLevel0 start="`\=(" end=")" skip="|.\{-}|" contains=@mvinlLambda,mvinlParen1
|
31
|
+
syn region mvinlParen1 contained matchgroup=hlLevel1 start="`\=(" end=")" skip="|.\{-}|" contains=@mvinlLambda,mvinlParen2
|
32
|
+
syn region mvinlParen2 contained matchgroup=hlLevel2 start="`\=(" end=")" skip="|.\{-}|" contains=@mvinlLambda,mvinlParen3
|
33
|
+
syn region mvinlParen3 contained matchgroup=hlLevel3 start="`\=(" end=")" skip="|.\{-}|" contains=@mvinlLambda,mvinlParen4
|
34
|
+
syn region mvinlParen4 contained matchgroup=hlLevel4 start="`\=(" end=")" skip="|.\{-}|" contains=@mvinlLambda,mvinlParen5
|
35
|
+
syn region mvinlParen5 contained matchgroup=hlLevel5 start="`\=(" end=")" skip="|.\{-}|" contains=@mvinlLambda,mvinlParen6
|
36
|
+
syn region mvinlParen6 contained matchgroup=hlLevel6 start="`\=(" end=")" skip="|.\{-}|" contains=@mvinlLambda,mvinlParen7
|
37
|
+
syn region mvinlParen7 contained matchgroup=hlLevel7 start="`\=(" end=")" skip="|.\{-}|" contains=@mvinlLambda,mvinlParen8
|
38
|
+
syn region mvinlParen8 contained matchgroup=hlLevel8 start="`\=(" end=")" skip="|.\{-}|" contains=@mvinlLambda,mvinlParen9
|
39
|
+
syn region mvinlParen9 contained matchgroup=hlLevel9 start="`\=(" end=")" skip="|.\{-}|" contains=@mvinlLambda,mvinlParen0
|
40
|
+
|
41
|
+
hi mvinlOperType guifg=#970096 ctermfg=95
|
42
|
+
|
43
|
+
hi! link mvinlOper mvinlOperType
|
44
|
+
hi link mvinlKeyword Keyword
|
45
|
+
hi link mvinlIdentifier Type
|
46
|
+
hi link mvinlNumber Number
|
47
|
+
hi link mvinlSymbol Constant
|
48
|
+
hi link mvinlString String
|
49
|
+
hi link mvinlKeywordArg Define
|
50
|
+
hi link mvinlGroup Identifier
|
51
|
+
hi link mvinlComment Comment
|
52
|
+
|
53
|
+
hi def hlLevel0 ctermfg=red guifg=red1
|
54
|
+
hi def hlLevel1 ctermfg=yellow guifg=orange1
|
55
|
+
hi def hlLevel2 ctermfg=green guifg=yellow1
|
56
|
+
hi def hlLevel3 ctermfg=cyan guifg=greenyellow
|
57
|
+
hi def hlLevel4 ctermfg=magenta guifg=green1
|
58
|
+
hi def hlLevel5 ctermfg=red guifg=springgreen1
|
59
|
+
hi def hlLevel6 ctermfg=yellow guifg=cyan1
|
60
|
+
hi def hlLevel7 ctermfg=green guifg=slateblue1
|
61
|
+
hi def hlLevel8 ctermfg=cyan guifg=magenta1
|
62
|
+
hi def hlLevel9 ctermfg=magenta guifg=purple1
|
63
|
+
|
data/lib/mvinl/info.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
# frozen-string-literal: true
|
2
|
+
|
3
|
+
# engine.rb
|
4
|
+
# Copyright (c) 2024, Daniel Sierpiński All rights reserved.
|
5
|
+
#
|
6
|
+
# See Copyright Notice in mvnil.rb
|
7
|
+
|
8
|
+
module MVinl
|
9
|
+
VERSION = '0.1.3'
|
10
|
+
Version = VERSION
|
11
|
+
Copyright = 'Copyright (c) 2024, Daniel Sierpiński'
|
12
|
+
end
|
data/lib/mvinl/lexer.rb
ADDED
@@ -0,0 +1,155 @@
|
|
1
|
+
# frozen-string-literal: true
|
2
|
+
|
3
|
+
=begin engine.rb
|
4
|
+
Copyright (c) 2024, Daniel Sierpiński All rights reserved.
|
5
|
+
|
6
|
+
See Copyright Notice in mvnil.rb
|
7
|
+
=end
|
8
|
+
|
9
|
+
require 'strscan'
|
10
|
+
|
11
|
+
module MVinl
|
12
|
+
class LexerError < StandardError; end
|
13
|
+
class UnexpectedTokenError < LexerError; end
|
14
|
+
|
15
|
+
class Lexer
|
16
|
+
attr_reader :eos
|
17
|
+
|
18
|
+
ID_REGEX = /[a-zA-Z_][a-zA-Z0-9_]*/
|
19
|
+
|
20
|
+
RESERVED = %w[def as style].freeze
|
21
|
+
|
22
|
+
TOKENS = {
|
23
|
+
KEYWORD: /#{RESERVED[0]}|#{RESERVED[1]}|#{RESERVED[2]}/,
|
24
|
+
OPEN_PAREN: /\(/,
|
25
|
+
CLOSE_PAREN: /\)/,
|
26
|
+
NEW_LINE: /(?:[ \t]*(?:\r?\n)[ \t]*)+/,
|
27
|
+
WHITESPACE: /[ \t]/,
|
28
|
+
KEYWORD_ARG: /(#{ID_REGEX}):/,
|
29
|
+
ID: ID_REGEX,
|
30
|
+
GROUP: /@(#{ID_REGEX})/,
|
31
|
+
NUMBER: /[+-]?\d+/,
|
32
|
+
STRING: /"((?:\\.|[^"\\])*)"/,
|
33
|
+
SYMBOL: /:(#{ID_REGEX})/,
|
34
|
+
COMMENT: /#/,
|
35
|
+
OPER: %r{[+\-*/%]},
|
36
|
+
END_TAG: /\./
|
37
|
+
}.freeze
|
38
|
+
|
39
|
+
def initialize(input)
|
40
|
+
@ss = StringScanner.new(input)
|
41
|
+
@args_n = 0
|
42
|
+
@in_group = false
|
43
|
+
@eos = false
|
44
|
+
end
|
45
|
+
|
46
|
+
def feed(input)
|
47
|
+
@ss = StringScanner.new(input)
|
48
|
+
end
|
49
|
+
|
50
|
+
def next_token
|
51
|
+
return process_eos if @ss.eos?
|
52
|
+
|
53
|
+
TOKENS.each do |type, regex|
|
54
|
+
if @ss.scan regex
|
55
|
+
@last_type = type
|
56
|
+
break
|
57
|
+
end
|
58
|
+
end
|
59
|
+
case @last_type
|
60
|
+
when :NEW_LINE
|
61
|
+
return next_token if continuation_line?
|
62
|
+
|
63
|
+
[:END_TAG, "\n"]
|
64
|
+
when :WHITESPACE
|
65
|
+
# Whitespace (' ' and '\t') does nothing in mvnl 0.1. I handle them
|
66
|
+
# though as indentation plays a role in 0.2 to predict position of elements
|
67
|
+
next_token
|
68
|
+
when :COMMENT
|
69
|
+
skip_to_next_line
|
70
|
+
next_token
|
71
|
+
when :OPEN_PAREN then [:OPEN_PAREN, '(']
|
72
|
+
when :CLOSE_PAREN
|
73
|
+
unless Parser::STATE[:depth].positive?
|
74
|
+
raise UnexpectedTokenError, 'CLOSE_PARAM found winth no matching OPEN_PARAM'
|
75
|
+
end
|
76
|
+
|
77
|
+
[:CLOSE_PAREN, ')']
|
78
|
+
when :OPER
|
79
|
+
unless Parser::STATE[:depth].positive?
|
80
|
+
raise UnexpectedTokenError, 'OPER found with no matching OPEN_PARAM'
|
81
|
+
end
|
82
|
+
|
83
|
+
[:OPER, @ss.matched]
|
84
|
+
when :KEYWORD
|
85
|
+
return [:DEF, @ss.matched] if @ss.matched == 'def'
|
86
|
+
|
87
|
+
[:KEYWORD, @ss.matched]
|
88
|
+
when :KEYWORD_ARG
|
89
|
+
if !Parser::STATE[:in_prop]
|
90
|
+
raise UnexpectedTokenError, 'Looking for identifier but found KEYWORD_ARG'
|
91
|
+
elsif Parser::STATE[:in_keyword_arg]
|
92
|
+
raise UnexpectedTokenError, 'Looking for a keyword argument value but found KEYWORD_ARG'
|
93
|
+
end
|
94
|
+
|
95
|
+
[:KEYWORD_ARG, @ss[1]]
|
96
|
+
when :GROUP
|
97
|
+
# Group gets canceled whenever encountered another group id or a matching end tag
|
98
|
+
if Parser::STATE[:in_keyword_arg]
|
99
|
+
raise UnexpectedTokenError, 'Looking for a keyword argument value but found GROUP'
|
100
|
+
end
|
101
|
+
|
102
|
+
@in_group = true
|
103
|
+
[:GROUP, @ss[1]]
|
104
|
+
when :ID then [:ID, @ss.matched]
|
105
|
+
when :NUMBER, :STRING, :SYMBOL
|
106
|
+
# Values can't be used outside an property or a lambda
|
107
|
+
if !Parser::STATE[:in_prop] && !Parser::STATE[:depth].positive?
|
108
|
+
raise UnexpectedTokenError, "Looking for ID or OPEN_PAREN but found #{@last_type}"
|
109
|
+
elsif !Parser::STATE[:in_keyword_arg] && Parser::STATE[:keyword_arg_depth].positive? &&
|
110
|
+
!Parser::STATE[:depth].positive?
|
111
|
+
raise UnexpectedTokenError, "Looking for END_TAG or KEYWORD_ARG but found #{@last_type}"
|
112
|
+
end
|
113
|
+
|
114
|
+
[@last_type, @ss[1] || @ss.matched]
|
115
|
+
when :END_TAG then [:END_TAG, '.']
|
116
|
+
else
|
117
|
+
raise UnexpectedTokenError, "Unexpected character: '#{@ss.getch}'"
|
118
|
+
end
|
119
|
+
rescue LexerError => e
|
120
|
+
warn "Syntax error at #{@ss.charpos - @ss.matched_size}: #{e}"
|
121
|
+
end
|
122
|
+
|
123
|
+
def tokenize
|
124
|
+
tokens = []
|
125
|
+
while (token = next_token)
|
126
|
+
warn "Tokenize: #{token}"
|
127
|
+
tokens << token
|
128
|
+
end
|
129
|
+
tokens
|
130
|
+
end
|
131
|
+
|
132
|
+
private
|
133
|
+
|
134
|
+
def continuation_line?
|
135
|
+
return true unless @in_group
|
136
|
+
|
137
|
+
# Auto end properties
|
138
|
+
lookahead = @ss.check(/\A(?:#{TOKENS[:GROUP]}|#{TOKENS[:ID]}$|#{TOKENS[:END_TAG]}|#{TOKENS[:NEW_LINE]})/)
|
139
|
+
warn "Continue? in_prop?: #{Parser::STATE[:in_prop].inspect}, lookahead: #{lookahead.inspect}"
|
140
|
+
Parser::STATE[:in_prop] ? !lookahead : true
|
141
|
+
end
|
142
|
+
|
143
|
+
# Move the cursor to the next new line tag
|
144
|
+
def skip_to_next_line
|
145
|
+
@ss.scan_until(/\n/) || @ss.terminate
|
146
|
+
end
|
147
|
+
|
148
|
+
def process_eos
|
149
|
+
return if @eos
|
150
|
+
|
151
|
+
@eos = true
|
152
|
+
[false, '$']
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
data/lib/mvinl/parser.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen-string-literal: true
|
2
|
+
|
3
|
+
=begin engine.rb
|
4
|
+
Copyright (c) 2024, Daniel Sierpiński All rights reserved.
|
5
|
+
|
6
|
+
See Copyright Notice in mvnil.rb
|
7
|
+
=end
|
8
|
+
|
9
|
+
require_relative '../../syntax/mvinl.tab'
|
10
|
+
|
11
|
+
class MVinl::Parser < MVinl::Program
|
12
|
+
def initialize(lexer, debug: false)
|
13
|
+
@yydebug = debug
|
14
|
+
@lexer = lexer
|
15
|
+
@tokens = []
|
16
|
+
@done = false
|
17
|
+
super()
|
18
|
+
end
|
19
|
+
|
20
|
+
def next_token
|
21
|
+
if @tokens.empty?
|
22
|
+
@lexer.next_token
|
23
|
+
else
|
24
|
+
@tokens.shift
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def enqueue_token(token)
|
29
|
+
@tokens << token
|
30
|
+
end
|
31
|
+
|
32
|
+
def finalize!
|
33
|
+
@done = true
|
34
|
+
end
|
35
|
+
|
36
|
+
def parsing_done?
|
37
|
+
@done && @tokens.empty?
|
38
|
+
end
|
39
|
+
|
40
|
+
def parse
|
41
|
+
do_parse
|
42
|
+
end
|
43
|
+
end
|
data/lib/mvinl.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen-string-literal: true
|
2
|
+
|
3
|
+
=begin engine.rb
|
4
|
+
Copyright (c) 2018, 2024, Daniel Sierpiński All rights reserved.
|
5
|
+
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
7
|
+
of this software and associated documentation files (the "Software"), to deal
|
8
|
+
in the Software without restriction, including without limitation the rights
|
9
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
10
|
+
copies of the Software, and to permit persons to whom the Software is
|
11
|
+
furnished to do so, subject to the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be included in
|
14
|
+
all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
17
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
18
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
19
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
20
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
21
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
22
|
+
THE SOFTWARE.
|
23
|
+
=end
|
24
|
+
|
25
|
+
require 'mvinl/parser'
|
26
|
+
require 'mvinl/lexer'
|
27
|
+
|
28
|
+
module MVinl
|
29
|
+
def self.eval(input)
|
30
|
+
parser = Parser.new(Lexer.new(input))
|
31
|
+
parser.parse
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.eval_from_file(path)
|
35
|
+
self.eval File.read(path)
|
36
|
+
end
|
37
|
+
end
|
data/mvinl.gemspec
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen-string-literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require 'mvinl/info'
|
6
|
+
|
7
|
+
GRAMMAR_FILE = 'syntax/mvinl.y'
|
8
|
+
COMPILED_FILE = 'syntax/mvinl.tab.rb'
|
9
|
+
|
10
|
+
Gem::Specification.new do |s|
|
11
|
+
s.name = 'mvinl'
|
12
|
+
s.version = MVinl::VERSION
|
13
|
+
s.authors = ['siery']
|
14
|
+
s.email = ['siery@comic.com']
|
15
|
+
s.summary = 'A simple configuration language made with RACC'
|
16
|
+
s.homepage = 'https://rubygems.org/gems/mvinl'
|
17
|
+
s.license = 'MIT'
|
18
|
+
s.metadata = { 'source_code_uri' => 'https://github.com/513ry/mvinl' }
|
19
|
+
s.required_ruby_version = '>= 3.2.0'
|
20
|
+
|
21
|
+
# Sify which files should be added to the gem when it is released.
|
22
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
23
|
+
s.files = Dir.chdir(File.expand_path(__dir__)) do
|
24
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|s|features)/}) }
|
25
|
+
end
|
26
|
+
# Compile syntax file
|
27
|
+
s.files.delete(GRAMMAR_FILE)
|
28
|
+
s.files << COMPILED_FILE
|
29
|
+
s.require_paths = %w[lib bin s rakelib syntax]
|
30
|
+
s.executables << 'imvnl'
|
31
|
+
|
32
|
+
s.add_dependency 'pp', '~> 0.6.2'
|
33
|
+
end
|
data/rakelib/build.rake
ADDED
data/spec/stack.mvnl
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
#
|
2
|
+
#
|
3
|
+
#
|
4
|
+
# MVinl stack configuration
|
5
|
+
|
6
|
+
# Definition with a single argument
|
7
|
+
def (mins x (% x 60))
|
8
|
+
|
9
|
+
# Definition with multiple arguments
|
10
|
+
def (perc x n (/ (* x 100) n))
|
11
|
+
|
12
|
+
@menu # First group runs as the initial state
|
13
|
+
Menu
|
14
|
+
New_Game: :state_next
|
15
|
+
Exit: :abord
|
16
|
+
|
17
|
+
@game
|
18
|
+
Mouse
|
19
|
+
Board 3 (+ 1 (+ 1 (+ 1)))
|
20
|
+
Button " Hello Vinl!"
|
21
|
+
line_height: (perc 2 8) padding: (* 2 4)
|
data/syntax/mvinl.tab.rb
ADDED
@@ -0,0 +1,519 @@
|
|
1
|
+
#
|
2
|
+
# DO NOT MODIFY!!!!
|
3
|
+
# This file is automatically generated by Racc 1.8.1
|
4
|
+
# from Racc grammar file "mvinl.y".
|
5
|
+
#
|
6
|
+
|
7
|
+
require 'racc/parser.rb'
|
8
|
+
module MVinl
|
9
|
+
class Program < Racc::Parser
|
10
|
+
|
11
|
+
module_eval(<<'...end mvinl.y/module_eval...', 'mvinl.y', 105)
|
12
|
+
|
13
|
+
FUNCTIONS = {}
|
14
|
+
STATE = {
|
15
|
+
in_prop: false,
|
16
|
+
in_keyword_arg: false,
|
17
|
+
keyword_arg_depth: 0,
|
18
|
+
depth: 0
|
19
|
+
}
|
20
|
+
|
21
|
+
class MVinl::ParserError < StandardError; end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def create_property(id, positional_args = [], keyword_args = {})
|
26
|
+
STATE[:in_prop] = false
|
27
|
+
{id => [positional_args, keyword_args]}
|
28
|
+
end
|
29
|
+
|
30
|
+
def create_group(properties)
|
31
|
+
properties || Hash.new
|
32
|
+
end
|
33
|
+
|
34
|
+
def define_function(name, args, body)
|
35
|
+
FUNCTIONS[name.to_sym] = {args: args, body: body}
|
36
|
+
nil
|
37
|
+
end
|
38
|
+
|
39
|
+
def evaluate_pn(operator, operands, context = {})
|
40
|
+
operands.map! do |op|
|
41
|
+
if op.is_a?(Array)
|
42
|
+
evaluate_pn(op[0], op[1..], context) # Nested PN expression
|
43
|
+
elsif context.key?(op)
|
44
|
+
context[op] # Function identifier
|
45
|
+
else
|
46
|
+
op # Literal value (e.g., NUMBER or STRING)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
if FUNCTIONS.key?(operator.to_sym)
|
51
|
+
function = FUNCTIONS[operator.to_sym]
|
52
|
+
raise MVinl::ParserError, "Argument mismatch for #{operator}" if operands.size != function[:args].size
|
53
|
+
|
54
|
+
# Map arguments to operands
|
55
|
+
new_context = function[:args].zip(operands).to_h
|
56
|
+
# Replace symbols in body with context values
|
57
|
+
function = replace_symbols(function[:body], new_context)
|
58
|
+
# Recursive evaluation
|
59
|
+
evaluate_pn(function[0], function[1..], new_context)
|
60
|
+
else
|
61
|
+
begin
|
62
|
+
operands.reduce(operator.to_sym)
|
63
|
+
rescue NoMethodError
|
64
|
+
raise MVinl::ParserError, "Unknown operator: #{operator}"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def replace_symbols(array, replacements)
|
70
|
+
array.map do |element|
|
71
|
+
if element.is_a?(Array)
|
72
|
+
replace_symbols(element, replacements)
|
73
|
+
elsif element.is_a?(Symbol) && replacements.key?(element)
|
74
|
+
replacements[element]
|
75
|
+
else
|
76
|
+
element
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
...end mvinl.y/module_eval...
|
81
|
+
##### State transition tables begin ###
|
82
|
+
|
83
|
+
racc_action_table = [
|
84
|
+
2, 8, 5, 6, 30, 26, 27, 28, 15, 7,
|
85
|
+
11, 11, 15, 15, 26, 27, 28, 15, 17, 11,
|
86
|
+
41, 48, 15, 26, 27, 28, 37, 41, 11, 41,
|
87
|
+
48, 15, 26, 27, 28, 43, nil, 11, 41, 15,
|
88
|
+
15, 26, 27, 28, nil, nil, 11, 41, nil, 15,
|
89
|
+
-14, -14, -14, -14, nil, nil, 11, -16, 26, 27,
|
90
|
+
28, nil, nil, 11, 26, 27, 28, nil, nil, 11 ]
|
91
|
+
|
92
|
+
racc_action_check = [
|
93
|
+
1, 2, 1, 1, 20, 21, 21, 21, 20, 1,
|
94
|
+
21, 7, 9, 21, 38, 38, 38, 10, 12, 38,
|
95
|
+
38, 38, 38, 39, 39, 39, 22, 31, 39, 39,
|
96
|
+
39, 39, 50, 50, 50, 32, nil, 50, 50, 32,
|
97
|
+
50, 51, 51, 51, nil, nil, 51, 51, nil, 51,
|
98
|
+
13, 13, 13, 13, nil, nil, 13, 18, 18, 18,
|
99
|
+
18, nil, nil, 18, 36, 36, 36, nil, nil, 36 ]
|
100
|
+
|
101
|
+
racc_action_pointer = [
|
102
|
+
nil, 0, 1, nil, nil, nil, nil, 0, nil, -2,
|
103
|
+
3, nil, 14, 45, nil, nil, nil, nil, 52, nil,
|
104
|
+
-6, -1, 21, nil, nil, nil, nil, nil, nil, nil,
|
105
|
+
nil, 15, 25, nil, nil, nil, 58, nil, 8, 17,
|
106
|
+
nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
|
107
|
+
26, 35, nil, nil, nil ]
|
108
|
+
|
109
|
+
racc_action_default = [
|
110
|
+
-1, -41, -41, -2, -3, -4, -6, -41, 55, -5,
|
111
|
+
-41, -30, -7, -9, -13, -40, -32, -8, -10, -12,
|
112
|
+
-41, -41, -11, -15, -20, -21, -22, -23, -24, -36,
|
113
|
+
-36, -35, -41, -33, -34, -17, -41, -19, -41, -41,
|
114
|
+
-25, -31, -32, -32, -18, -28, -37, -38, -39, -29,
|
115
|
+
-41, -41, -26, -35, -27 ]
|
116
|
+
|
117
|
+
racc_goto_table = [
|
118
|
+
10, 14, 16, 34, 23, 38, 39, 1, 21, 40,
|
119
|
+
3, 4, 29, 9, 32, 12, 45, 49, 13, 18,
|
120
|
+
22, 19, 44, 35, 42, 36, 31, nil, 52, 54,
|
121
|
+
47, 47, 34, 34, 50, 51, nil, nil, nil, nil,
|
122
|
+
nil, nil, nil, 32, 32 ]
|
123
|
+
|
124
|
+
racc_goto_check = [
|
125
|
+
15, 10, 10, 14, 11, 19, 19, 1, 16, 18,
|
126
|
+
2, 3, 10, 4, 15, 5, 18, 18, 6, 7,
|
127
|
+
8, 9, 11, 12, 10, 13, 17, nil, 18, 18,
|
128
|
+
10, 10, 14, 14, 16, 16, nil, nil, nil, nil,
|
129
|
+
nil, nil, nil, 15, 15 ]
|
130
|
+
|
131
|
+
racc_goto_pointer = [
|
132
|
+
nil, 7, 9, 10, 7, 6, 9, 6, 2, 8,
|
133
|
+
-8, -14, 1, 3, -18, -7, -8, 5, -22, -24 ]
|
134
|
+
|
135
|
+
racc_goto_default = [
|
136
|
+
nil, nil, nil, nil, nil, nil, nil, nil, nil, 25,
|
137
|
+
33, 46, nil, nil, 24, 20, nil, 53, nil, nil ]
|
138
|
+
|
139
|
+
racc_reduce_table = [
|
140
|
+
0, 0, :racc_error,
|
141
|
+
0, 16, :_reduce_1,
|
142
|
+
2, 16, :_reduce_2,
|
143
|
+
2, 16, :_reduce_3,
|
144
|
+
2, 16, :_reduce_4,
|
145
|
+
2, 17, :_reduce_5,
|
146
|
+
0, 19, :_reduce_6,
|
147
|
+
2, 19, :_reduce_7,
|
148
|
+
3, 19, :_reduce_8,
|
149
|
+
1, 20, :_reduce_9,
|
150
|
+
2, 20, :_reduce_10,
|
151
|
+
3, 20, :_reduce_11,
|
152
|
+
2, 20, :_reduce_12,
|
153
|
+
1, 21, :_reduce_13,
|
154
|
+
0, 22, :_reduce_14,
|
155
|
+
2, 22, :_reduce_15,
|
156
|
+
0, 23, :_reduce_16,
|
157
|
+
2, 23, :_reduce_17,
|
158
|
+
2, 27, :_reduce_18,
|
159
|
+
1, 28, :_reduce_19,
|
160
|
+
1, 26, :_reduce_20,
|
161
|
+
1, 26, :_reduce_21,
|
162
|
+
1, 29, :_reduce_22,
|
163
|
+
1, 29, :_reduce_23,
|
164
|
+
1, 29, :_reduce_24,
|
165
|
+
6, 18, :_reduce_25,
|
166
|
+
4, 32, :_reduce_26,
|
167
|
+
4, 32, :_reduce_27,
|
168
|
+
4, 24, :_reduce_28,
|
169
|
+
4, 24, :_reduce_29,
|
170
|
+
1, 30, :_reduce_30,
|
171
|
+
1, 33, :_reduce_31,
|
172
|
+
0, 31, :_reduce_32,
|
173
|
+
2, 31, :_reduce_33,
|
174
|
+
2, 31, :_reduce_34,
|
175
|
+
2, 31, :_reduce_35,
|
176
|
+
0, 34, :_reduce_36,
|
177
|
+
2, 34, :_reduce_37,
|
178
|
+
2, 34, :_reduce_38,
|
179
|
+
2, 34, :_reduce_39,
|
180
|
+
1, 25, :_reduce_40 ]
|
181
|
+
|
182
|
+
racc_reduce_n = 41
|
183
|
+
|
184
|
+
racc_shift_n = 55
|
185
|
+
|
186
|
+
racc_token_table = {
|
187
|
+
false => 0,
|
188
|
+
:error => 1,
|
189
|
+
:EOS => 2,
|
190
|
+
:GROUP => 3,
|
191
|
+
:END_TAG => 4,
|
192
|
+
:KEYWORD_ARG => 5,
|
193
|
+
:NUMBER => 6,
|
194
|
+
:STRING => 7,
|
195
|
+
:SYMBOL => 8,
|
196
|
+
:DEF => 9,
|
197
|
+
:OPER => 10,
|
198
|
+
:OPEN_PAREN => 11,
|
199
|
+
:CLOSE_PAREN => 12,
|
200
|
+
:polish_notation => 13,
|
201
|
+
:ID => 14 }
|
202
|
+
|
203
|
+
racc_nt_base = 15
|
204
|
+
|
205
|
+
racc_use_result_var = false
|
206
|
+
|
207
|
+
Racc_arg = [
|
208
|
+
racc_action_table,
|
209
|
+
racc_action_check,
|
210
|
+
racc_action_default,
|
211
|
+
racc_action_pointer,
|
212
|
+
racc_goto_table,
|
213
|
+
racc_goto_check,
|
214
|
+
racc_goto_default,
|
215
|
+
racc_goto_pointer,
|
216
|
+
racc_nt_base,
|
217
|
+
racc_reduce_table,
|
218
|
+
racc_token_table,
|
219
|
+
racc_shift_n,
|
220
|
+
racc_reduce_n,
|
221
|
+
racc_use_result_var ]
|
222
|
+
Ractor.make_shareable(Racc_arg) if defined?(Ractor)
|
223
|
+
|
224
|
+
Racc_token_to_s_table = [
|
225
|
+
"$end",
|
226
|
+
"error",
|
227
|
+
"EOS",
|
228
|
+
"GROUP",
|
229
|
+
"END_TAG",
|
230
|
+
"KEYWORD_ARG",
|
231
|
+
"NUMBER",
|
232
|
+
"STRING",
|
233
|
+
"SYMBOL",
|
234
|
+
"DEF",
|
235
|
+
"OPER",
|
236
|
+
"OPEN_PAREN",
|
237
|
+
"CLOSE_PAREN",
|
238
|
+
"polish_notation",
|
239
|
+
"ID",
|
240
|
+
"$start",
|
241
|
+
"program",
|
242
|
+
"group",
|
243
|
+
"function_def",
|
244
|
+
"properties",
|
245
|
+
"property",
|
246
|
+
"prop_id",
|
247
|
+
"positional_args",
|
248
|
+
"keyword_args",
|
249
|
+
"lambda",
|
250
|
+
"identifier",
|
251
|
+
"super_value",
|
252
|
+
"keyword_arg",
|
253
|
+
"keyword_arg_id",
|
254
|
+
"value",
|
255
|
+
"open_paren",
|
256
|
+
"args",
|
257
|
+
"polish_notation_def",
|
258
|
+
"close_paren",
|
259
|
+
"params" ]
|
260
|
+
Ractor.make_shareable(Racc_token_to_s_table) if defined?(Ractor)
|
261
|
+
|
262
|
+
Racc_debug_parser = false
|
263
|
+
|
264
|
+
##### State transition tables end #####
|
265
|
+
|
266
|
+
# reduce 0 omitted
|
267
|
+
|
268
|
+
module_eval(<<'.,.,', 'mvinl.y', 12)
|
269
|
+
def _reduce_1(val, _values)
|
270
|
+
Hash.new
|
271
|
+
end
|
272
|
+
.,.,
|
273
|
+
|
274
|
+
module_eval(<<'.,.,', 'mvinl.y', 13)
|
275
|
+
def _reduce_2(val, _values)
|
276
|
+
val[0].merge(val[1])
|
277
|
+
end
|
278
|
+
.,.,
|
279
|
+
|
280
|
+
module_eval(<<'.,.,', 'mvinl.y', 14)
|
281
|
+
def _reduce_3(val, _values)
|
282
|
+
val[0]
|
283
|
+
end
|
284
|
+
.,.,
|
285
|
+
|
286
|
+
module_eval(<<'.,.,', 'mvinl.y', 15)
|
287
|
+
def _reduce_4(val, _values)
|
288
|
+
val[0]
|
289
|
+
end
|
290
|
+
.,.,
|
291
|
+
|
292
|
+
module_eval(<<'.,.,', 'mvinl.y', 18)
|
293
|
+
def _reduce_5(val, _values)
|
294
|
+
{val[0].to_sym => create_group(val[1])}
|
295
|
+
end
|
296
|
+
.,.,
|
297
|
+
|
298
|
+
module_eval(<<'.,.,', 'mvinl.y', 21)
|
299
|
+
def _reduce_6(val, _values)
|
300
|
+
Hash.new
|
301
|
+
end
|
302
|
+
.,.,
|
303
|
+
|
304
|
+
module_eval(<<'.,.,', 'mvinl.y', 22)
|
305
|
+
def _reduce_7(val, _values)
|
306
|
+
val[0].merge(val[1])
|
307
|
+
end
|
308
|
+
.,.,
|
309
|
+
|
310
|
+
module_eval(<<'.,.,', 'mvinl.y', 23)
|
311
|
+
def _reduce_8(val, _values)
|
312
|
+
val[0].merge(val[1])
|
313
|
+
end
|
314
|
+
.,.,
|
315
|
+
|
316
|
+
module_eval(<<'.,.,', 'mvinl.y', 26)
|
317
|
+
def _reduce_9(val, _values)
|
318
|
+
create_property(val[0])
|
319
|
+
end
|
320
|
+
.,.,
|
321
|
+
|
322
|
+
module_eval(<<'.,.,', 'mvinl.y', 27)
|
323
|
+
def _reduce_10(val, _values)
|
324
|
+
create_property(val[0], val[1])
|
325
|
+
end
|
326
|
+
.,.,
|
327
|
+
|
328
|
+
module_eval(<<'.,.,', 'mvinl.y', 28)
|
329
|
+
def _reduce_11(val, _values)
|
330
|
+
create_property(val[0], val[1], val[2])
|
331
|
+
end
|
332
|
+
.,.,
|
333
|
+
|
334
|
+
module_eval(<<'.,.,', 'mvinl.y', 29)
|
335
|
+
def _reduce_12(val, _values)
|
336
|
+
create_property(val[0], val[1])
|
337
|
+
end
|
338
|
+
.,.,
|
339
|
+
|
340
|
+
module_eval(<<'.,.,', 'mvinl.y', 32)
|
341
|
+
def _reduce_13(val, _values)
|
342
|
+
STATE[:in_prop] = true; val[0]
|
343
|
+
end
|
344
|
+
.,.,
|
345
|
+
|
346
|
+
module_eval(<<'.,.,', 'mvinl.y', 35)
|
347
|
+
def _reduce_14(val, _values)
|
348
|
+
Array.new
|
349
|
+
end
|
350
|
+
.,.,
|
351
|
+
|
352
|
+
module_eval(<<'.,.,', 'mvinl.y', 36)
|
353
|
+
def _reduce_15(val, _values)
|
354
|
+
val[0] << val[1]
|
355
|
+
end
|
356
|
+
.,.,
|
357
|
+
|
358
|
+
module_eval(<<'.,.,', 'mvinl.y', 39)
|
359
|
+
def _reduce_16(val, _values)
|
360
|
+
Hash.new
|
361
|
+
end
|
362
|
+
.,.,
|
363
|
+
|
364
|
+
module_eval(<<'.,.,', 'mvinl.y', 42)
|
365
|
+
def _reduce_17(val, _values)
|
366
|
+
STATE[:keyword_arg_depth] = 0
|
367
|
+
val[0].merge(val[1])
|
368
|
+
|
369
|
+
end
|
370
|
+
.,.,
|
371
|
+
|
372
|
+
module_eval(<<'.,.,', 'mvinl.y', 49)
|
373
|
+
def _reduce_18(val, _values)
|
374
|
+
STATE[:in_keyword_arg] = false
|
375
|
+
STATE[:keyword_arg_depth] += 1
|
376
|
+
{val[0].to_sym => val[1]}
|
377
|
+
|
378
|
+
end
|
379
|
+
.,.,
|
380
|
+
|
381
|
+
module_eval(<<'.,.,', 'mvinl.y', 55)
|
382
|
+
def _reduce_19(val, _values)
|
383
|
+
STATE[:in_keyword_arg] = true; val[0]
|
384
|
+
end
|
385
|
+
.,.,
|
386
|
+
|
387
|
+
module_eval(<<'.,.,', 'mvinl.y', 58)
|
388
|
+
def _reduce_20(val, _values)
|
389
|
+
val[0]
|
390
|
+
end
|
391
|
+
.,.,
|
392
|
+
|
393
|
+
module_eval(<<'.,.,', 'mvinl.y', 59)
|
394
|
+
def _reduce_21(val, _values)
|
395
|
+
val[0]
|
396
|
+
end
|
397
|
+
.,.,
|
398
|
+
|
399
|
+
module_eval(<<'.,.,', 'mvinl.y', 62)
|
400
|
+
def _reduce_22(val, _values)
|
401
|
+
val[0].to_i
|
402
|
+
end
|
403
|
+
.,.,
|
404
|
+
|
405
|
+
module_eval(<<'.,.,', 'mvinl.y', 63)
|
406
|
+
def _reduce_23(val, _values)
|
407
|
+
val[0]
|
408
|
+
end
|
409
|
+
.,.,
|
410
|
+
|
411
|
+
module_eval(<<'.,.,', 'mvinl.y', 64)
|
412
|
+
def _reduce_24(val, _values)
|
413
|
+
val[0].to_sym
|
414
|
+
end
|
415
|
+
.,.,
|
416
|
+
|
417
|
+
module_eval(<<'.,.,', 'mvinl.y', 69)
|
418
|
+
def _reduce_25(val, _values)
|
419
|
+
define_function(val[2], val[3], val[4])
|
420
|
+
|
421
|
+
end
|
422
|
+
.,.,
|
423
|
+
|
424
|
+
module_eval(<<'.,.,', 'mvinl.y', 73)
|
425
|
+
def _reduce_26(val, _values)
|
426
|
+
[val[1], *val[2]]
|
427
|
+
end
|
428
|
+
.,.,
|
429
|
+
|
430
|
+
module_eval(<<'.,.,', 'mvinl.y', 74)
|
431
|
+
def _reduce_27(val, _values)
|
432
|
+
[val[1], *val[2]]
|
433
|
+
end
|
434
|
+
.,.,
|
435
|
+
|
436
|
+
module_eval(<<'.,.,', 'mvinl.y', 77)
|
437
|
+
def _reduce_28(val, _values)
|
438
|
+
evaluate_pn(val[1], val[2])
|
439
|
+
end
|
440
|
+
.,.,
|
441
|
+
|
442
|
+
module_eval(<<'.,.,', 'mvinl.y', 78)
|
443
|
+
def _reduce_29(val, _values)
|
444
|
+
evaluate_pn(val[1], val[2])
|
445
|
+
end
|
446
|
+
.,.,
|
447
|
+
|
448
|
+
module_eval(<<'.,.,', 'mvinl.y', 81)
|
449
|
+
def _reduce_30(val, _values)
|
450
|
+
STATE[:depth] += 1
|
451
|
+
end
|
452
|
+
.,.,
|
453
|
+
|
454
|
+
module_eval(<<'.,.,', 'mvinl.y', 84)
|
455
|
+
def _reduce_31(val, _values)
|
456
|
+
STATE[:depth] -= 1
|
457
|
+
end
|
458
|
+
.,.,
|
459
|
+
|
460
|
+
module_eval(<<'.,.,', 'mvinl.y', 87)
|
461
|
+
def _reduce_32(val, _values)
|
462
|
+
Array.new
|
463
|
+
end
|
464
|
+
.,.,
|
465
|
+
|
466
|
+
module_eval(<<'.,.,', 'mvinl.y', 88)
|
467
|
+
def _reduce_33(val, _values)
|
468
|
+
val[0] << val[1]
|
469
|
+
end
|
470
|
+
.,.,
|
471
|
+
|
472
|
+
module_eval(<<'.,.,', 'mvinl.y', 89)
|
473
|
+
def _reduce_34(val, _values)
|
474
|
+
val[0] << val[1]
|
475
|
+
end
|
476
|
+
.,.,
|
477
|
+
|
478
|
+
module_eval(<<'.,.,', 'mvinl.y', 90)
|
479
|
+
def _reduce_35(val, _values)
|
480
|
+
val[0] << val[1]
|
481
|
+
end
|
482
|
+
.,.,
|
483
|
+
|
484
|
+
module_eval(<<'.,.,', 'mvinl.y', 93)
|
485
|
+
def _reduce_36(val, _values)
|
486
|
+
Array.new
|
487
|
+
end
|
488
|
+
.,.,
|
489
|
+
|
490
|
+
module_eval(<<'.,.,', 'mvinl.y', 94)
|
491
|
+
def _reduce_37(val, _values)
|
492
|
+
val[0] << val[1]
|
493
|
+
end
|
494
|
+
.,.,
|
495
|
+
|
496
|
+
module_eval(<<'.,.,', 'mvinl.y', 95)
|
497
|
+
def _reduce_38(val, _values)
|
498
|
+
val[0] << val[1]
|
499
|
+
end
|
500
|
+
.,.,
|
501
|
+
|
502
|
+
module_eval(<<'.,.,', 'mvinl.y', 96)
|
503
|
+
def _reduce_39(val, _values)
|
504
|
+
val[0] << val[1]
|
505
|
+
end
|
506
|
+
.,.,
|
507
|
+
|
508
|
+
module_eval(<<'.,.,', 'mvinl.y', 99)
|
509
|
+
def _reduce_40(val, _values)
|
510
|
+
val[0].to_sym
|
511
|
+
end
|
512
|
+
.,.,
|
513
|
+
|
514
|
+
def _reduce_none(val, _values)
|
515
|
+
val[0]
|
516
|
+
end
|
517
|
+
|
518
|
+
end # class Program
|
519
|
+
end # module MVinl
|
metadata
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mvinl
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.3
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- siery
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2024-12-06 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: pp
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.6.2
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.6.2
|
27
|
+
description:
|
28
|
+
email:
|
29
|
+
- siery@comic.com
|
30
|
+
executables:
|
31
|
+
- imvnl
|
32
|
+
extensions: []
|
33
|
+
extra_rdoc_files: []
|
34
|
+
files:
|
35
|
+
- ".gitignore"
|
36
|
+
- ".ruby-version"
|
37
|
+
- Gemfile
|
38
|
+
- LICENSE
|
39
|
+
- README.md
|
40
|
+
- Rakefile
|
41
|
+
- bin/imvnl
|
42
|
+
- edit/mvinl.vim
|
43
|
+
- lib/mvinl.rb
|
44
|
+
- lib/mvinl/info.rb
|
45
|
+
- lib/mvinl/lexer.rb
|
46
|
+
- lib/mvinl/parser.rb
|
47
|
+
- mvinl.gemspec
|
48
|
+
- rakelib/build.rake
|
49
|
+
- spec/stack.mvnl
|
50
|
+
- syntax/mvinl.tab.rb
|
51
|
+
homepage: https://rubygems.org/gems/mvinl
|
52
|
+
licenses:
|
53
|
+
- MIT
|
54
|
+
metadata:
|
55
|
+
source_code_uri: https://github.com/513ry/mvinl
|
56
|
+
post_install_message:
|
57
|
+
rdoc_options: []
|
58
|
+
require_paths:
|
59
|
+
- lib
|
60
|
+
- bin
|
61
|
+
- s
|
62
|
+
- rakelib
|
63
|
+
- syntax
|
64
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 3.2.0
|
69
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '0'
|
74
|
+
requirements: []
|
75
|
+
rubygems_version: 3.5.16
|
76
|
+
signing_key:
|
77
|
+
specification_version: 4
|
78
|
+
summary: A simple configuration language made with RACC
|
79
|
+
test_files: []
|