skeem 0.2.15 → 0.2.16
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/.rubocop.yml +17 -11
- data/CHANGELOG.md +5 -0
- data/Gemfile +2 -0
- data/README.md +3 -2
- data/Rakefile +2 -0
- data/appveyor.yml +3 -4
- data/bin/skeem +15 -15
- data/lib/skeem.rb +2 -0
- data/lib/skeem/datum_dsl.rb +12 -3
- data/lib/skeem/element_visitor.rb +5 -2
- data/lib/skeem/grammar.rb +86 -24
- data/lib/skeem/interpreter.rb +5 -3
- data/lib/skeem/parser.rb +6 -4
- data/lib/skeem/primitive/primitive_builder.rb +128 -115
- data/lib/skeem/primitive/primitive_procedure.rb +17 -20
- data/lib/skeem/runtime.rb +9 -5
- data/lib/skeem/s_expr_builder.rb +46 -104
- data/lib/skeem/s_expr_nodes.rb +116 -90
- data/lib/skeem/skeem_exception.rb +0 -0
- data/lib/skeem/skm_binding.rb +6 -7
- data/lib/skeem/skm_compound_datum.rb +8 -4
- data/lib/skeem/skm_element.rb +14 -12
- data/lib/skeem/skm_empty_list.rb +6 -4
- data/lib/skeem/skm_exception.rb +9 -0
- data/lib/skeem/skm_expression.rb +3 -1
- data/lib/skeem/skm_frame.rb +3 -2
- data/lib/skeem/skm_pair.rb +23 -18
- data/lib/skeem/skm_procedure_exec.rb +8 -6
- data/lib/skeem/skm_simple_datum.rb +13 -12
- data/lib/skeem/skm_unary_expression.rb +15 -17
- data/lib/skeem/tokenizer.rb +32 -25
- data/lib/skeem/version.rb +3 -1
- data/skeem.gemspec +6 -4
- data/spec/skeem/add4.skm +4 -0
- data/spec/skeem/datum_dsl_spec.rb +13 -12
- data/spec/skeem/element_visitor_spec.rb +12 -10
- data/spec/skeem/interpreter_spec.rb +74 -46
- data/spec/skeem/lambda_spec.rb +9 -7
- data/spec/skeem/parser_spec.rb +21 -19
- data/spec/skeem/primitive/primitive_builder_spec.rb +57 -48
- data/spec/skeem/primitive/primitive_procedure_spec.rb +15 -13
- data/spec/skeem/runtime_spec.rb +18 -16
- data/spec/skeem/s_expr_nodes_spec.rb +8 -6
- data/spec/skeem/skm_compound_datum_spec.rb +11 -9
- data/spec/skeem/skm_element_spec.rb +7 -5
- data/spec/skeem/skm_empty_list_spec.rb +7 -5
- data/spec/skeem/skm_frame_spec.rb +5 -4
- data/spec/skeem/skm_pair_spec.rb +4 -3
- data/spec/skeem/skm_procedure_exec_spec.rb +2 -0
- data/spec/skeem/skm_simple_datum_spec.rb +24 -22
- data/spec/skeem/skm_unary_expression_spec.rb +11 -9
- data/spec/skeem/tokenizer_spec.rb +53 -44
- data/spec/skeem_spec.rb +2 -0
- data/spec/spec_helper.rb +4 -2
- metadata +7 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c6b187bafcc1084e3c45a68f552bb5756b8dc51338f5241fa64ad5f60f1f94c7
|
4
|
+
data.tar.gz: f6925b7497ab8a2ab678c7b5483907b374caed4f7a9b00e1d22d3d53c141191c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b8e2cd533cd3e1661f1c205ab87179e8d1a48a1e23d5c5867c6106f54b56fe076fda0ae2eaa1a28045633dc4e3eb80ec891abf8dd3f03f6698e53c5e308173be
|
7
|
+
data.tar.gz: 68e3b66e4821062f9792e37b9b2d89134e10a21fcb6f0e3fc1a591243a1be8930cb5a18fcc9add86850a47cbfa9be4f7c2a2239bb94e3f187082efb2a2392412
|
data/.rubocop.yml
CHANGED
@@ -5,6 +5,9 @@ AllCops:
|
|
5
5
|
Layout/CaseIndentation:
|
6
6
|
Enabled: false
|
7
7
|
|
8
|
+
Layout/ClosingHeredocIndentation:
|
9
|
+
Enabled: false
|
10
|
+
|
8
11
|
Layout/CommentIndentation:
|
9
12
|
Enabled: false
|
10
13
|
|
@@ -13,7 +16,7 @@ Layout/ElseAlignment:
|
|
13
16
|
|
14
17
|
Layout/EmptyLines:
|
15
18
|
Enabled: false
|
16
|
-
|
19
|
+
|
17
20
|
Layout/EndAlignment:
|
18
21
|
Enabled: false
|
19
22
|
|
@@ -26,10 +29,10 @@ Layout/IndentationWidth:
|
|
26
29
|
|
27
30
|
Layout/IndentationConsistency:
|
28
31
|
Enabled: true
|
29
|
-
|
32
|
+
|
30
33
|
Layout/IndentHeredoc:
|
31
34
|
Enabled: false
|
32
|
-
|
35
|
+
|
33
36
|
Layout/MultilineHashBraceLayout:
|
34
37
|
Enabled: true
|
35
38
|
|
@@ -38,10 +41,10 @@ Layout/SpaceAroundOperators:
|
|
38
41
|
|
39
42
|
Layout/SpaceInsideParens:
|
40
43
|
Enabled: true
|
41
|
-
|
44
|
+
|
42
45
|
Layout/Tab:
|
43
46
|
Enabled: true
|
44
|
-
|
47
|
+
|
45
48
|
Layout/TrailingBlankLines:
|
46
49
|
Enabled: true
|
47
50
|
|
@@ -100,10 +103,10 @@ Naming/ConstantName:
|
|
100
103
|
|
101
104
|
Naming/ClassAndModuleCamelCase:
|
102
105
|
Enabled: false
|
103
|
-
|
106
|
+
|
104
107
|
Naming/UncommunicativeBlockParamName:
|
105
108
|
Enabled: true
|
106
|
-
|
109
|
+
|
107
110
|
Naming/UncommunicativeMethodParamName:
|
108
111
|
Enabled: false
|
109
112
|
|
@@ -167,12 +170,15 @@ Style/InverseMethods:
|
|
167
170
|
Style/Next:
|
168
171
|
Enabled: false
|
169
172
|
|
173
|
+
Style/NumericLiterals:
|
174
|
+
Enabled: false
|
175
|
+
|
170
176
|
Style/RaiseArgs:
|
171
177
|
Enabled: true
|
172
178
|
|
173
179
|
Style/RedundantReturn:
|
174
180
|
Enabled: false
|
175
|
-
|
181
|
+
|
176
182
|
Style/RedundantSelf:
|
177
183
|
Enabled: true
|
178
184
|
|
@@ -181,15 +187,15 @@ Style/RegexpLiteral:
|
|
181
187
|
|
182
188
|
Style/PercentLiteralDelimiters:
|
183
189
|
Enabled: false
|
184
|
-
|
190
|
+
|
185
191
|
Style/StderrPuts:
|
186
|
-
Enabled: false
|
192
|
+
Enabled: false
|
187
193
|
|
188
194
|
Style/StringLiterals:
|
189
195
|
Enabled: true
|
190
196
|
|
191
197
|
Style/TernaryParentheses:
|
192
198
|
Enabled: false
|
193
|
-
|
199
|
+
|
194
200
|
Style/UnlessElse:
|
195
201
|
Enabled: false
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
## [0.2.16] - 2019-08-18
|
2
|
+
- Code refactoring to use string frozen magic comments (as a consequence, srl_ruby runs only on Rubies 2.3 or newer).
|
3
|
+
- Code restyling to please rubocop 0.7.40.
|
4
|
+
|
5
|
+
|
1
6
|
## [0.2.15] - 2019-07-02
|
2
7
|
- Added a basic command-line and console interface for Skeem interpreter.
|
3
8
|
- Added procedures: `display!`, `newline`, `make-list`
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -32,7 +32,8 @@ If you're not familiar to Scheme, the section [About Scheme](#about-scheme) cont
|
|
32
32
|
|
33
33
|
## Usage
|
34
34
|
Once the gem is installed, the `skeem` executable can be used.
|
35
|
-
It allows to run the interpreter from the command line.
|
35
|
+
It allows to run the interpreter from a REPL console or from the command line.
|
36
|
+
Another way to interact with the Skeem interpreter is to embed it in your Ruby code.
|
36
37
|
|
37
38
|
### Launching a REPL session
|
38
39
|
To start a REPL (Read-Eval-Print-Loop) session, just type:
|
@@ -42,7 +43,7 @@ To start a REPL (Read-Eval-Print-Loop) session, just type:
|
|
42
43
|
|
43
44
|
Skeem displays a greeting, a prompt and then waits for your input:
|
44
45
|
```
|
45
|
-
Welcome to Skeem 0.2.
|
46
|
+
Welcome to Skeem 0.2.16.
|
46
47
|
>
|
47
48
|
```
|
48
49
|
|
data/Rakefile
CHANGED
data/appveyor.yml
CHANGED
@@ -1,17 +1,16 @@
|
|
1
1
|
version: '{build}'
|
2
|
-
max_jobs:
|
2
|
+
max_jobs: 5
|
3
3
|
environment:
|
4
4
|
matrix:
|
5
|
+
- Ruby_version: 26-x64
|
5
6
|
- Ruby_version: 25-x64
|
6
7
|
- Ruby_version: 24-x64
|
7
8
|
- Ruby_version: 23-x64
|
9
|
+
- Ruby_version: 26
|
8
10
|
- Ruby_version: 25
|
9
11
|
- Ruby_version: 24
|
10
12
|
- Ruby_version: 23
|
11
13
|
|
12
|
-
# These are failing
|
13
|
-
# - Ruby_version: 26
|
14
|
-
# - Ruby_version: 26-x64
|
15
14
|
|
16
15
|
install:
|
17
16
|
- set PATH=C:\Ruby%Ruby_version%\bin;%PATH%
|
data/bin/skeem
CHANGED
@@ -1,20 +1,22 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
4
|
require 'skeem'
|
4
5
|
|
5
6
|
class SkeemREPL
|
6
7
|
attr_reader :interpreter
|
7
8
|
|
8
|
-
def initialize
|
9
|
+
def initialize
|
9
10
|
@interpreter = Skeem::Interpreter.new
|
10
11
|
end
|
11
12
|
|
12
13
|
def run_session
|
13
|
-
puts "Welcome to Skeem #{Skeem::VERSION}."
|
14
|
+
puts "Welcome to Skeem #{Skeem::VERSION}."
|
14
15
|
loop do
|
15
16
|
print '> '
|
16
17
|
input = gets.chomp.strip
|
17
|
-
break if
|
18
|
+
break if %w[(quit) (exit)].include?(input)
|
19
|
+
|
18
20
|
process_input(input)
|
19
21
|
end
|
20
22
|
end
|
@@ -22,15 +24,13 @@ class SkeemREPL
|
|
22
24
|
def run_file(aFilename)
|
23
25
|
if File.exist?(aFilename)
|
24
26
|
valid_fname = aFilename
|
25
|
-
|
26
|
-
if File.
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
valid_fname = nil
|
33
|
-
end
|
27
|
+
elsif File.extname(aFilename).empty? # Retry by adding extension...
|
28
|
+
if File.exist?(aFilename + '.skm')
|
29
|
+
valid_fname = aFilename + '.skm'
|
30
|
+
elsif File.exist?(aFilename + '.scm')
|
31
|
+
valid_fname = aFilename + '.scm'
|
32
|
+
else
|
33
|
+
valid_fname = nil
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
@@ -43,8 +43,8 @@ class SkeemREPL
|
|
43
43
|
def process_input(input)
|
44
44
|
begin
|
45
45
|
ptree = interpreter.parse(input)
|
46
|
-
rescue StandardError =>
|
47
|
-
$stderr.puts
|
46
|
+
rescue StandardError => e
|
47
|
+
$stderr.puts e.message
|
48
48
|
return
|
49
49
|
end
|
50
50
|
|
@@ -69,4 +69,4 @@ if ARGV.empty?
|
|
69
69
|
djinn.run_session
|
70
70
|
else
|
71
71
|
djinn.run_file(ARGV[0])
|
72
|
-
end
|
72
|
+
end
|
data/lib/skeem.rb
CHANGED
data/lib/skeem/datum_dsl.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative 'skm_simple_datum'
|
2
4
|
require_relative 'skm_compound_datum'
|
3
5
|
require_relative 'skm_pair'
|
@@ -19,6 +21,7 @@ module Skeem
|
|
19
21
|
else
|
20
22
|
raise StandardError, aBoolean.inspect
|
21
23
|
end
|
24
|
+
result
|
22
25
|
end
|
23
26
|
|
24
27
|
def integer(aLiteral)
|
@@ -32,6 +35,7 @@ module Skeem
|
|
32
35
|
else
|
33
36
|
raise StandardError, aLiteral.inspect
|
34
37
|
end
|
38
|
+
result
|
35
39
|
end
|
36
40
|
|
37
41
|
def rational(aLiteral)
|
@@ -45,6 +49,7 @@ module Skeem
|
|
45
49
|
else
|
46
50
|
raise StandardError, aLiteral.inspect
|
47
51
|
end
|
52
|
+
result
|
48
53
|
end
|
49
54
|
|
50
55
|
def real(aLiteral)
|
@@ -58,6 +63,7 @@ module Skeem
|
|
58
63
|
else
|
59
64
|
raise StandardError, aLiteral.inspect
|
60
65
|
end
|
66
|
+
result
|
61
67
|
end
|
62
68
|
|
63
69
|
def char(aLiteral)
|
@@ -75,6 +81,7 @@ module Skeem
|
|
75
81
|
else
|
76
82
|
raise StandardError, aLiteral.inspect
|
77
83
|
end
|
84
|
+
result
|
78
85
|
end
|
79
86
|
|
80
87
|
def string(aLiteral)
|
@@ -88,6 +95,7 @@ module Skeem
|
|
88
95
|
else
|
89
96
|
SkmString.create(aLiteral.to_s)
|
90
97
|
end
|
98
|
+
result
|
91
99
|
end
|
92
100
|
|
93
101
|
def identifier(aLiteral)
|
@@ -101,6 +109,7 @@ module Skeem
|
|
101
109
|
else
|
102
110
|
raise StandardError, aLiteral.inspect
|
103
111
|
end
|
112
|
+
result
|
104
113
|
end
|
105
114
|
|
106
115
|
alias symbol identifier
|
@@ -150,7 +159,7 @@ module Skeem
|
|
150
159
|
SkmBoolean.create(aLiteral)
|
151
160
|
when String
|
152
161
|
parse_literal(aLiteral)
|
153
|
-
when SkmPair
|
162
|
+
when SkmPair # Special case: not a PORO literal
|
154
163
|
# One assumes that a Skeem list contains only Skeem datum objects
|
155
164
|
SkmPair.create_from_a(aLiteral.to_a)
|
156
165
|
when SkmUndefined
|
@@ -158,6 +167,7 @@ module Skeem
|
|
158
167
|
else
|
159
168
|
raise StandardError, aLiteral.inspect
|
160
169
|
end
|
170
|
+
result
|
161
171
|
end
|
162
172
|
|
163
173
|
private
|
@@ -177,6 +187,5 @@ module Skeem
|
|
177
187
|
string(aLiteral)
|
178
188
|
end
|
179
189
|
end
|
180
|
-
|
181
190
|
end # module
|
182
|
-
end # module
|
191
|
+
end # module
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Skeem
|
2
4
|
class SkmElementVisitor
|
3
5
|
# Link to the root element to visit
|
@@ -12,6 +14,7 @@ module Skeem
|
|
12
14
|
# @param aRoot [SkmElement] the parse tree to visit.
|
13
15
|
def initialize(aRoot)
|
14
16
|
raise StandardError if aRoot.nil?
|
17
|
+
|
15
18
|
@root = aRoot
|
16
19
|
@subscribers = []
|
17
20
|
end
|
@@ -57,7 +60,6 @@ module Skeem
|
|
57
60
|
broadcast(:after_empty_list, anEmptyList)
|
58
61
|
end
|
59
62
|
|
60
|
-
|
61
63
|
def visit_pair(aPair)
|
62
64
|
broadcast(:before_pair, aPair)
|
63
65
|
traverse_car_cdr(aPair)
|
@@ -110,8 +112,9 @@ module Skeem
|
|
110
112
|
def broadcast(msg, *args)
|
111
113
|
subscribers.each do |subscr|
|
112
114
|
next unless subscr.respond_to?(msg) || subscr.respond_to?(:accept_all)
|
115
|
+
|
113
116
|
subscr.send(msg, runtime, *args)
|
114
117
|
end
|
115
118
|
end
|
116
119
|
end # class
|
117
|
-
end # module
|
120
|
+
end # module
|
data/lib/skeem/grammar.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# Grammar for Skeem (a subset of Scheme language)
|
2
4
|
require 'rley' # Load the gem
|
3
5
|
|
@@ -11,7 +13,7 @@ module Skeem
|
|
11
13
|
# Delimiters, separators...
|
12
14
|
add_terminals('APOSTROPHE', 'COMMA', 'COMMA_AT_SIGN')
|
13
15
|
add_terminals('GRAVE_ACCENT', 'LPAREN', 'RPAREN')
|
14
|
-
add_terminals('PERIOD', 'ARROW')
|
16
|
+
add_terminals('PERIOD', 'UNDERSCORE', 'ARROW', 'ELLIPSIS')
|
15
17
|
add_terminals('VECTOR_BEGIN')
|
16
18
|
|
17
19
|
# Literal values...
|
@@ -19,9 +21,9 @@ module Skeem
|
|
19
21
|
add_terminals('CHAR', 'STRING_LIT', 'IDENTIFIER')
|
20
22
|
|
21
23
|
# Keywords...
|
22
|
-
add_terminals('BEGIN', 'COND', 'DEFINE', '
|
23
|
-
add_terminals('IF', 'LAMBDA', 'LET', 'LET*')
|
24
|
-
add_terminals('QUOTE', 'QUASIQUOTE', 'SET!')
|
24
|
+
add_terminals('BEGIN', 'COND', 'DEFINE', 'DEFINE-SYNTAX', 'DO')
|
25
|
+
add_terminals('ELSE', 'IF', 'INCLUDE', 'LAMBDA', 'LET', 'LET*')
|
26
|
+
add_terminals('QUOTE', 'QUASIQUOTE', 'SET!', 'SYNTAX-RULES')
|
25
27
|
add_terminals('UNQUOTE', 'UNQUOTE-SPLICING')
|
26
28
|
|
27
29
|
rule('program' => 'cmd_or_def_plus').as 'main'
|
@@ -33,6 +35,7 @@ module Skeem
|
|
33
35
|
rule 'command' => 'expression'
|
34
36
|
rule('definition' => 'LPAREN DEFINE IDENTIFIER expression RPAREN').as 'definition'
|
35
37
|
rule('definition' => 'LPAREN DEFINE LPAREN IDENTIFIER def_formals RPAREN body RPAREN').as 'alt_definition'
|
38
|
+
rule('definition' => 'syntax_definition')
|
36
39
|
rule('definition' => 'LPAREN BEGIN definition_star RPAREN').as 'definitions_within_begin'
|
37
40
|
rule('expression' => 'IDENTIFIER').as 'variable_reference'
|
38
41
|
rule 'expression' => 'literal'
|
@@ -41,8 +44,9 @@ module Skeem
|
|
41
44
|
rule 'expression' => 'conditional'
|
42
45
|
rule 'expression' => 'assignment'
|
43
46
|
rule 'expression' => 'derived_expression'
|
47
|
+
rule 'expression' => 'includer'
|
44
48
|
rule 'literal' => 'quotation'
|
45
|
-
rule 'literal' => 'self-evaluating'
|
49
|
+
rule 'literal' => 'self-evaluating'
|
46
50
|
rule('quotation' => 'APOSTROPHE datum').as 'quotation_short'
|
47
51
|
rule('quotation' => 'LPAREN QUOTE datum RPAREN').as 'quotation'
|
48
52
|
rule 'self-evaluating' => 'BOOLEAN'
|
@@ -64,8 +68,8 @@ module Skeem
|
|
64
68
|
rule('vector' => 'VECTOR_BEGIN datum_star RPAREN').as 'vector'
|
65
69
|
rule('datum_plus' => 'datum_plus datum').as 'multiple_datums'
|
66
70
|
rule('datum_plus' => 'datum').as 'last_datum'
|
67
|
-
rule('datum_star' => 'datum_star datum').as '
|
68
|
-
rule('datum_star' => []).as 'no_datum_yet'
|
71
|
+
rule('datum_star' => 'datum_star datum').as 'star_default'
|
72
|
+
rule('datum_star' => []).as 'star_base' ## 'no_datum_yet'
|
69
73
|
rule 'symbol' => 'IDENTIFIER'
|
70
74
|
rule('procedure_call' => 'LPAREN operator RPAREN').as 'proc_call_nullary'
|
71
75
|
rule('procedure_call' => 'LPAREN operator operand_plus RPAREN').as 'proc_call_args'
|
@@ -79,16 +83,17 @@ module Skeem
|
|
79
83
|
rule('formals' => 'LPAREN identifier_star RPAREN').as 'fixed_arity_formals'
|
80
84
|
rule('formals' => 'IDENTIFIER').as 'variadic_formals'
|
81
85
|
rule('formals' => 'LPAREN identifier_plus PERIOD IDENTIFIER RPAREN').as 'dotted_formals'
|
82
|
-
rule('
|
83
|
-
rule('identifier_star' =>
|
86
|
+
rule('syntax_definition' => 'LPAREN DEFINE-SYNTAX keyword transformer_spec RPAREN').as 'syntax_definition'
|
87
|
+
rule('identifier_star' => 'identifier_star IDENTIFIER').as 'star_default'
|
88
|
+
rule('identifier_star' => []).as 'star_base' ## 'no_identifier_yet'
|
84
89
|
rule('identifier_plus' => 'identifier_plus IDENTIFIER').as 'multiple_identifiers'
|
85
90
|
rule('identifier_plus' => 'IDENTIFIER').as 'last_identifier'
|
86
91
|
rule('body' => 'definition_star sequence').as 'body'
|
87
|
-
rule('definition_star' => 'definition_star definition').as '
|
88
|
-
rule('definition_star' => []).as 'no_definition_yet'
|
92
|
+
rule('definition_star' => 'definition_star definition').as 'star_default'
|
93
|
+
rule('definition_star' => []).as 'star_base' ## 'no_definition_yet'
|
89
94
|
rule('sequence' => 'command_star expression').as 'sequence'
|
90
|
-
rule('command_star' => 'command_star command').as '
|
91
|
-
rule('command_star' => []).as 'no_command_yet'
|
95
|
+
rule('command_star' => 'command_star command').as 'star_default'
|
96
|
+
rule('command_star' => []).as 'star_base' ## 'no_command_yet'
|
92
97
|
rule('conditional' => 'LPAREN IF test consequent alternate RPAREN').as 'conditional'
|
93
98
|
rule 'test' => 'expression'
|
94
99
|
rule 'consequent' => 'expression'
|
@@ -101,13 +106,15 @@ module Skeem
|
|
101
106
|
rule('derived_expression' => 'LPAREN COND cond_clause_plus RPAREN').as 'cond_form'
|
102
107
|
rule('derived_expression' => 'LPAREN COND cond_clause_star LPAREN ELSE sequence RPAREN RPAREN').as 'cond_else_form'
|
103
108
|
rule('derived_expression' => 'LPAREN LET LPAREN binding_spec_star RPAREN body RPAREN').as 'short_let_form'
|
109
|
+
# TODO: implement "named let"
|
110
|
+
rule('derived_expression' => 'LPAREN LET IDENTIFIER LPAREN binding_spec_star RPAREN body RPAREN') # .as 'named_form'
|
104
111
|
rule('derived_expression' => 'LPAREN LET* LPAREN binding_spec_star RPAREN body RPAREN').as 'let_star_form'
|
105
112
|
|
106
|
-
# As the R7RS grammar is too restrictive,
|
113
|
+
# As the R7RS grammar is too restrictive,
|
107
114
|
# the next rule was made more general than its standard counterpart
|
108
115
|
rule('derived_expression' => 'LPAREN BEGIN body RPAREN').as 'begin_expression'
|
109
116
|
do_syntax = <<-END_SYNTAX
|
110
|
-
LPAREN DO LPAREN iteration_spec_star RPAREN
|
117
|
+
LPAREN DO LPAREN iteration_spec_star RPAREN
|
111
118
|
LPAREN test do_result RPAREN
|
112
119
|
command_star RPAREN
|
113
120
|
END_SYNTAX
|
@@ -115,25 +122,29 @@ END_SYNTAX
|
|
115
122
|
rule 'derived_expression' => 'quasiquotation'
|
116
123
|
rule('cond_clause_plus' => 'cond_clause_plus cond_clause').as 'multiple_cond_clauses'
|
117
124
|
rule('cond_clause_plus' => 'cond_clause').as 'last_cond_clauses'
|
118
|
-
rule('cond_clause_star' => 'cond_clause_star cond_clause').as '
|
119
|
-
rule('cond_clause_star' => []).as 'last_cond_clauses_star'
|
125
|
+
rule('cond_clause_star' => 'cond_clause_star cond_clause').as 'star_default'
|
126
|
+
rule('cond_clause_star' => []).as 'star_base' ## 'last_cond_clauses_star'
|
120
127
|
rule('cond_clause' => 'LPAREN test sequence RPAREN').as 'cond_clause'
|
121
128
|
rule('cond_clause' => 'LPAREN test RPAREN')
|
122
129
|
rule('cond_clause' => 'LPAREN test ARROW recipient RPAREN').as 'cond_arrow_clause'
|
123
130
|
rule('recipient' => 'expression')
|
124
131
|
rule('quasiquotation' => 'LPAREN QUASIQUOTE qq_template RPAREN').as 'quasiquotation'
|
125
132
|
rule('quasiquotation' => 'GRAVE_ACCENT qq_template').as 'quasiquotation_short'
|
126
|
-
rule('binding_spec_star' => 'binding_spec_star binding_spec').as '
|
127
|
-
rule('binding_spec_star' => []).as 'no_binding_spec_yet'
|
133
|
+
rule('binding_spec_star' => 'binding_spec_star binding_spec').as 'star_default'
|
134
|
+
rule('binding_spec_star' => []).as 'star_base' ## 'no_binding_spec_yet'
|
128
135
|
rule('binding_spec' => 'LPAREN IDENTIFIER expression RPAREN').as 'binding_spec'
|
129
|
-
rule('iteration_spec_star' => 'iteration_spec_star iteration_spec').as '
|
130
|
-
rule('iteration_spec_star' => []).as 'no_iter_spec_yet'
|
136
|
+
rule('iteration_spec_star' => 'iteration_spec_star iteration_spec').as 'star_default'
|
137
|
+
rule('iteration_spec_star' => []).as 'star_base' ## 'no_iter_spec_yet'
|
131
138
|
rule('iteration_spec' => 'LPAREN IDENTIFIER init step RPAREN').as 'iteration_spec_long'
|
132
139
|
rule('iteration_spec' => 'LPAREN IDENTIFIER init RPAREN').as 'iteration_spec_short'
|
133
140
|
rule('init' => 'expression')
|
134
141
|
rule('step' => 'expression')
|
135
142
|
rule 'do_result' => 'sequence'
|
136
|
-
rule('do_result' => []).as 'empty_do_result'
|
143
|
+
rule('do_result' => []).as 'star_base' ## 'empty_do_result'
|
144
|
+
rule('keyword' => 'IDENTIFIER')
|
145
|
+
rule('includer' => 'LPAREN INCLUDE string_plus RPAREN').as 'include'
|
146
|
+
rule('string_plus' => 'string_plus STRING_LIT').as 'multiple_string'
|
147
|
+
rule('string_plus' => 'STRING_LIT').as 'last_single_string'
|
137
148
|
rule 'qq_template' => 'simple_datum'
|
138
149
|
rule 'qq_template' => 'list_qq_template'
|
139
150
|
rule 'qq_template' => 'vector_qq_template'
|
@@ -144,14 +155,65 @@ END_SYNTAX
|
|
144
155
|
rule('vector_qq_template' => 'VECTOR_BEGIN qq_template_or_splice_star RPAREN').as 'vector_qq'
|
145
156
|
rule('unquotation' => 'COMMA qq_template').as 'unquotation_short'
|
146
157
|
rule 'unquotation' => 'LPAREN UNQUOTE qq_template RPAREN'
|
147
|
-
rule('qq_template_or_splice_star' => 'qq_template_or_splice_star qq_template_or_splice').as '
|
148
|
-
rule('qq_template_or_splice_star' => []).as 'no_template_splice_yet'
|
158
|
+
rule('qq_template_or_splice_star' => 'qq_template_or_splice_star qq_template_or_splice').as 'star_default'
|
159
|
+
rule('qq_template_or_splice_star' => []).as 'star_base' ## 'no_template_splice_yet'
|
149
160
|
rule 'qq_template_or_splice_plus' => 'qq_template_or_splice_plus qq_template_or_splice'
|
150
161
|
rule 'qq_template_or_splice_plus' => 'qq_template_or_splice'
|
151
162
|
rule 'qq_template_or_splice' => 'qq_template'
|
152
163
|
rule 'qq_template_or_splice' => 'splicing_unquotation'
|
153
164
|
rule 'splicing_unquotation' => 'COMMA_AT_SIGN qq_template'
|
154
165
|
rule 'splicing_unquotation' => 'LPAREN UNQUOTE-SPLICING qq_template RPAREN'
|
166
|
+
rule('transformer_spec' => 'LPAREN SYNTAX-RULES LPAREN identifier_star RPAREN syntax_rule_star RPAREN').as 'transformer_syntax'
|
167
|
+
rule('transformer_spec' => 'LPAREN SYNTAX-RULES IDENTIFIER LPAREN identifier_star RPAREN syntax_rule_star RPAREN')
|
168
|
+
rule('syntax_rule_star' => 'syntax_rule_star syntax_rule').as 'star_default'
|
169
|
+
rule('syntax_rule_star' => []).as 'star_base'
|
170
|
+
rule('syntax_rule' => 'LPAREN pattern template RPAREN').as 'syntax_rule'
|
171
|
+
rule('pattern' => 'pattern_identifier')
|
172
|
+
rule('pattern' => 'UNDERSCORE')
|
173
|
+
rule('pattern' => 'LPAREN pattern_star RPAREN')
|
174
|
+
rule('pattern' => 'LPAREN pattern_plus PERIOD pattern RPAREN')
|
175
|
+
rule('pattern' => 'LPAREN pattern_plus ELLIPSIS pattern_star RPAREN')
|
176
|
+
rule('pattern' => 'LPAREN pattern_plus ELLIPSIS pattern_star PERIOD pattern RPAREN')
|
177
|
+
rule('pattern' => 'VECTOR_BEGIN pattern_star RPAREN')
|
178
|
+
rule('pattern' => 'VECTOR_BEGIN pattern_plus ELLIPSIS pattern_star RPAREN')
|
179
|
+
rule('pattern' => 'pattern_datum')
|
180
|
+
rule('pattern_star' => 'pattern_star pattern').as 'star_default'
|
181
|
+
rule('pattern_star' => []).as 'star_base'
|
182
|
+
rule('pattern_plus' => 'pattern_plus pattern')
|
183
|
+
rule('pattern_plus' => 'pattern')
|
184
|
+
rule('pattern_datum' => 'STRING_LIT')
|
185
|
+
rule('pattern_datum' => 'CHAR')
|
186
|
+
rule('pattern_datum' => 'BOOLEAN')
|
187
|
+
rule('pattern_datum' => 'number')
|
188
|
+
# rule('pattern_datum' => 'bytevector')
|
189
|
+
rule('template' => 'pattern_identifier')
|
190
|
+
rule('template' => 'LPAREN template_element_star RPAREN')
|
191
|
+
rule('template' => 'LPAREN template_element_plus PERIOD template RPAREN')
|
192
|
+
rule('template' => 'VECTOR_BEGIN template_element_star RPAREN')
|
193
|
+
rule('template' => 'template_datum')
|
194
|
+
rule('template_element_star' => 'template_element_star template_element').as 'star_default'
|
195
|
+
rule('template_element_star' => []).as 'star_base'
|
196
|
+
rule('template_element_plus' => 'template_element_plus template_element')
|
197
|
+
rule('template_element_plus' => 'template_element')
|
198
|
+
rule('template_element' => 'template')
|
199
|
+
rule('template_element' => 'template ELLIPSIS')
|
200
|
+
rule('template_datum' => 'pattern_datum')
|
201
|
+
rule('pattern_identifier' => 'IDENTIFIER')
|
202
|
+
# Ugly: specailized production rule per keyword...
|
203
|
+
rule('pattern_identifier' => 'BEGIN')
|
204
|
+
rule('pattern_identifier' => 'COND')
|
205
|
+
rule('pattern_identifier' => 'DEFINE')
|
206
|
+
rule('pattern_identifier' => 'ELSE')
|
207
|
+
rule('pattern_identifier' => 'IF')
|
208
|
+
rule('pattern_identifier' => 'INCLUDE')
|
209
|
+
rule('pattern_identifier' => 'LAMBDA')
|
210
|
+
rule('pattern_identifier' => 'LET')
|
211
|
+
rule('pattern_identifier' => 'LET*')
|
212
|
+
rule('pattern_identifier' => 'QUOTE')
|
213
|
+
rule('pattern_identifier' => 'QUASIQUOTE')
|
214
|
+
rule('pattern_identifier' => 'SET!')
|
215
|
+
rule('pattern_identifier' => 'UNQUOTE')
|
216
|
+
rule('pattern_identifier' => 'UNQUOTE-SPLICING')
|
155
217
|
end
|
156
218
|
|
157
219
|
# And now build the grammar and make it accessible via a global constant
|