skeem 0.2.14 → 0.2.18
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 +451 -195
- data/.travis.yml +27 -0
- data/CHANGELOG.md +35 -1
- data/Gemfile +2 -0
- data/README.md +125 -56
- data/Rakefile +2 -0
- data/appveyor.yml +3 -4
- data/bin/cubic.skm +4 -0
- data/bin/hello-world.skm +1 -0
- data/bin/skeem +72 -0
- data/lib/skeem/datum_dsl.rb +40 -30
- data/lib/skeem/element_visitor.rb +5 -2
- data/lib/skeem/grammar.rb +88 -26
- data/lib/skeem/interpreter.rb +9 -7
- data/lib/skeem/parser.rb +6 -4
- data/lib/skeem/primitive/primitive_builder.rb +148 -122
- data/lib/skeem/primitive/primitive_procedure.rb +23 -25
- data/lib/skeem/runtime.rb +17 -15
- data/lib/skeem/s_expr_builder.rb +49 -117
- data/lib/skeem/s_expr_nodes.rb +147 -132
- data/lib/skeem/skeem_exception.rb +1 -0
- data/lib/skeem/skm_binding.rb +9 -11
- data/lib/skeem/skm_compound_datum.rb +9 -6
- data/lib/skeem/skm_element.rb +15 -13
- 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 +26 -18
- data/lib/skeem/skm_procedure_exec.rb +11 -6
- data/lib/skeem/skm_simple_datum.rb +23 -20
- data/lib/skeem/skm_unary_expression.rb +34 -37
- data/lib/skeem/standard/base.skm +4 -0
- data/lib/skeem/tokenizer.rb +38 -28
- data/lib/skeem/version.rb +3 -1
- data/lib/skeem.rb +2 -0
- data/skeem.gemspec +9 -6
- data/spec/skeem/add4.skm +4 -0
- data/spec/skeem/datum_dsl_spec.rb +13 -12
- data/spec/skeem/element_visitor_spec.rb +14 -10
- data/spec/skeem/interpreter_spec.rb +84 -44
- data/spec/skeem/lambda_spec.rb +13 -11
- data/spec/skeem/parser_spec.rb +23 -19
- data/spec/skeem/primitive/primitive_builder_spec.rb +65 -48
- data/spec/skeem/primitive/primitive_procedure_spec.rb +14 -12
- data/spec/skeem/runtime_spec.rb +20 -18
- data/spec/skeem/s_expr_nodes_spec.rb +8 -6
- data/spec/skeem/skm_compound_datum_spec.rb +12 -10
- 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 +9 -8
- 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 +54 -43
- data/spec/skeem_spec.rb +2 -0
- data/spec/spec_helper.rb +15 -10
- metadata +18 -10
data/.travis.yml
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
language: ruby
|
2
|
+
dist: trusty
|
3
|
+
|
4
|
+
before_install:
|
5
|
+
- gem update --system
|
6
|
+
- gem install bundler
|
7
|
+
|
8
|
+
script:
|
9
|
+
- bundle exec rake
|
10
|
+
|
11
|
+
rvm:
|
12
|
+
- 2.6.3
|
13
|
+
- 2.5.5
|
14
|
+
- 2.4.6
|
15
|
+
- 2.3.8
|
16
|
+
- jruby-9.1.9.0
|
17
|
+
|
18
|
+
matrix:
|
19
|
+
allow_failures:
|
20
|
+
- rvm: ruby-head
|
21
|
+
- rvm: jruby-head
|
22
|
+
|
23
|
+
|
24
|
+
# whitelist
|
25
|
+
branches:
|
26
|
+
only:
|
27
|
+
- master
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,39 @@
|
|
1
|
+
## [0.2.18] - 2021-08-29
|
2
|
+
- Minor refactoring for Rley 0.8.03
|
3
|
+
- Code restyling to please rubocop 1.19.1.
|
4
|
+
|
5
|
+
### Changed
|
6
|
+
- File `.rubocop.yml` updated with newer Rubocop cops
|
7
|
+
- File `grammar.rb`: Calling `Rley::grammar_builder`, replace `LET*` token by `LET_STAR`
|
8
|
+
- Other files changed to get rid of Rubocop offences
|
9
|
+
|
10
|
+
## [0.2.17] - 2020-05-09
|
11
|
+
- Updated `.rubocop.yml` file.
|
12
|
+
- Code restyling to please rubocop 0.8.0.
|
13
|
+
|
14
|
+
## [0.2.16] - 2019-08-18
|
15
|
+
- Code refactoring to use string frozen magic comments (as a consequence, srl_ruby runs only on Rubies 2.3 or newer).
|
16
|
+
- Code restyling to please rubocop 0.7.40.
|
17
|
+
|
18
|
+
## [0.2.15] - 2019-07-02
|
19
|
+
- Added a basic command-line and console interface for Skeem interpreter.
|
20
|
+
- Added procedures: `display!`, `newline`, `make-list`
|
21
|
+
|
22
|
+
### Added
|
23
|
+
- `bin/skeem` The CLI and REPL console implementation for Skeem
|
24
|
+
- `bin/cubic.skm`: A sample defining a procedure that computes the cube of a number.
|
25
|
+
- `bin/hello-world.skm`: The initiatic programming example
|
26
|
+
|
27
|
+
### Changed
|
28
|
+
- File `primitive_builder.rb` Implementation of primitive procedures `newline`, `make-list`
|
29
|
+
- File `base.skm` Added implementation of `newline` procedure.
|
30
|
+
- File `README.md` vastly reorganized and introducing the new command line.
|
31
|
+
|
32
|
+
### Removed
|
33
|
+
- Bundler-generated files `bin/console`, `bin/setup`
|
34
|
+
|
1
35
|
## [0.2.14] - 2019-06-29
|
2
|
-
- Added derived expression
|
36
|
+
- Added derived expression `do` as an imperative iteration form.
|
3
37
|
- Added procedures: `vector-set!`
|
4
38
|
|
5
39
|
### Added
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -26,23 +26,74 @@ Or install it yourself as:
|
|
26
26
|
$ gem install skeem
|
27
27
|
|
28
28
|
|
29
|
-
The __Skeem__ project
|
29
|
+
The __Skeem__ project is WIP and currently the gem supports a subset of the __Scheme__ language.
|
30
|
+
If you're not familiar to Scheme, the section [About Scheme](#about-scheme) contains a number of interesting pointers.
|
30
31
|
|
31
|
-
## About Scheme
|
32
32
|
|
33
|
-
|
33
|
+
## Usage
|
34
|
+
Once the gem is installed, the `skeem` executable can be used.
|
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.
|
34
37
|
|
35
|
-
###
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
- [The Scheme Programming Language, 4th Edition](https://www.scheme.com/tspl4/) by Kent Dybvig. A complete, introductory textbook on Scheme based on the older R5RS standard.
|
41
|
-
- [Teach Yourself Scheme in Fixnum Days](http://ds26gte.github.io/tyscheme/index.html) by Dorai Sitaram
|
42
|
-
- [Yet Another Scheme Tutorial](http://www.shido.info/lisp/idx_scm_e.html) by Shido Takafumi
|
43
|
-
- [An Introduction to Scheme and its Implementation](http://www.cs.utexas.edu/ftp/garbage/cs345/schintro-v14/schintro_toc.html) by Paul R. Wilson
|
38
|
+
### Launching a REPL session
|
39
|
+
To start a REPL (Read-Eval-Print-Loop) session, just type:
|
40
|
+
```
|
41
|
+
skeem
|
42
|
+
```
|
44
43
|
|
45
|
-
|
44
|
+
Skeem displays a greeting, a prompt and then waits for your input:
|
45
|
+
```
|
46
|
+
Welcome to Skeem 0.2.16.
|
47
|
+
>
|
48
|
+
```
|
49
|
+
|
50
|
+
Now that we know that `Skeem` is well alive, let's kick it...
|
51
|
+
We begin with the ritual 'Hello world' example, by typing after the __>__ prompt:
|
52
|
+
```
|
53
|
+
(display "Hello, world")
|
54
|
+
```
|
55
|
+
|
56
|
+
Skeem then replies:
|
57
|
+
```
|
58
|
+
Hello, world
|
59
|
+
Skeem::SkmUndefined
|
60
|
+
```
|
61
|
+
|
62
|
+
This works as expected except, maybe, for the last line. It can be easily explained if one knows
|
63
|
+
that the return value of the `display` procedure is undefined in standard Scheme.
|
64
|
+
Internally Skeem, implements such undefined result as a `Skeem::Undefined`instance.
|
65
|
+
|
66
|
+
To give some taste of things, here is an excerpt from a REPL session:
|
67
|
+
```
|
68
|
+
> (+ 4 (* 5 6))
|
69
|
+
34
|
70
|
+
> (define x 6)
|
71
|
+
6
|
72
|
+
> (+ (* 5 x x) (* 4 x) 3)
|
73
|
+
207
|
74
|
+
> (/ 21 5)
|
75
|
+
21/5
|
76
|
+
> (/ 21.0 5)
|
77
|
+
21/5
|
78
|
+
```
|
79
|
+
|
80
|
+
#### Terminating a REPL session
|
81
|
+
To exit a REPL session, call the `exit` procedure as follows:
|
82
|
+
```
|
83
|
+
(exit)
|
84
|
+
```
|
85
|
+
|
86
|
+
### Running a Skeem file
|
87
|
+
To run a Scheme file:
|
88
|
+
|
89
|
+
```
|
90
|
+
skeem path/to/some-file.skm
|
91
|
+
```
|
92
|
+
|
93
|
+
By the way, the `/bin` folder of the `skeem` gem contains a couple of Skeem sample files.
|
94
|
+
|
95
|
+
## Embed Skeem in your Ruby app
|
96
|
+
This is the third way for Rubyists to interact with Skeem by integrating it directly in their Ruby code.
|
46
97
|
|
47
98
|
### Example 1 (Variable definition)
|
48
99
|
|
@@ -195,6 +246,51 @@ Here are a few pointers for the Scheme programming language:
|
|
195
246
|
- Iteration (`do`)
|
196
247
|
- Control procedures
|
197
248
|
|
249
|
+
### Standard library
|
250
|
+
This section lists the procedures following closely the official [Revised7 Report on the Algorithmic Language](https://bitbucket.org/cowan/r7rs/src/draft-10/rnrs/r7rs.pdf) standard.
|
251
|
+
|
252
|
+
#### Equivalence predicates
|
253
|
+
* `eqv?`, `equal?`
|
254
|
+
|
255
|
+
#### Boolean procedures
|
256
|
+
* `boolean?`, `boolean=?`, `and`, `or`, `not`
|
257
|
+
|
258
|
+
#### Character procedures
|
259
|
+
* `char?` `char->integer`, `char=?`, `char<?`, `char>?`,`char<=?`, `char>=?`
|
260
|
+
|
261
|
+
#### Numerical operations
|
262
|
+
* Number-level: `number?`, `complex?`, `real?`, `rational?`, `integer?`, `zero?`,
|
263
|
+
`exact?`, `inexact?`, `exact-integer?` , `+`, `-`, `*`, `/`, `=`, `square`, `number->string`
|
264
|
+
* Real-level: `positive?`, `negative?`, `<`, `>`, `<=`, `>=`, `abs`, `max`, `min`,
|
265
|
+
`floor/`, `floor-quotient`, `floor-remainder`, `truncate/`, `truncate-quotient`,
|
266
|
+
`truncate-remainder`, `quotient`, `remainder`, `modulo`, `gcd`, `lcm`, `numerator`,
|
267
|
+
`denominator`, `floor`, `ceiling`, `truncate`, `round`
|
268
|
+
* Integer-level: `even?`, `odd?`, `integer->char`
|
269
|
+
|
270
|
+
#### List procedures
|
271
|
+
* `list?`, `null?`, `pair?`, `append`, `car`, `cdr`, `caar`, `cadr`, `cdar`, `cddr`,
|
272
|
+
`cons`, `make-list`, `length`, `list`, `list-copy`, `list->vector`, `reverse`,
|
273
|
+
`set-car!`, `set-cdr!`, `assq`, `assv`
|
274
|
+
|
275
|
+
#### String procedures
|
276
|
+
* `string?`, `string=?`, `string`, `make-string`, `string-append`, `string-length`, `string->symbol`
|
277
|
+
|
278
|
+
#### Symbol procedures
|
279
|
+
* `symbol?`, `symbol=?`, `symbol->string`
|
280
|
+
|
281
|
+
#### Vector procedures
|
282
|
+
* `vector?`, `make-vector`, `vector`, `vector-length`, `vector-set!`, `vector->list`
|
283
|
+
|
284
|
+
#### Control procedures
|
285
|
+
* `procedure?`, `apply`, `map`
|
286
|
+
|
287
|
+
#### Input/output procedures
|
288
|
+
* `display`, `newline`
|
289
|
+
|
290
|
+
#### Non-standard procedures
|
291
|
+
* `assert`
|
292
|
+
|
293
|
+
|
198
294
|
### Standard syntactic forms
|
199
295
|
#### define
|
200
296
|
__Purpose:__ Create a new variable and bind an expression/value to it.
|
@@ -254,56 +350,29 @@ __Purpose:__ Define one or more variable local to the block.
|
|
254
350
|
__Syntax:__
|
255
351
|
* (let* (<binding_spec\*\>) <body\>)
|
256
352
|
|
257
|
-
### Standard library
|
258
|
-
This section lists the implemented standard procedures
|
259
|
-
|
260
|
-
#### Equivalence predicates
|
261
|
-
* `eqv?`, `equal?`
|
262
|
-
|
263
|
-
#### Boolean procedures
|
264
|
-
* `boolean?`, `boolean=?`, `and`, `or`, `not`
|
265
|
-
|
266
|
-
#### Character procedures
|
267
|
-
* `char?` `char->integer`, `char=?`, `char<?`, `char>?`,`char<=?`, `char>=?`
|
268
|
-
|
269
|
-
#### Numerical operations
|
270
|
-
* Number-level: `number?`, `complex?`, `real?`, `rational?`, `integer?`, `zero?`, `exact?`, `inexact?`, `exact-integer?` , `+`, `-`, `*`, `/`,
|
271
|
-
`=`, `square`, `number->string`
|
272
|
-
* Real-level: `positive?`, `negative?`, `<`, `>`, `<=`, `>=`, `abs`, `max`, `min`, `floor/`, `floor-quotient`, `floor-remainder`, `truncate/`, `truncate-quotient`,
|
273
|
-
`truncate-remainder`, `quotient`, `remainder`, `modulo`, `gcd`, `lcm`, `numerator`, `denominator`, `floor`, `ceiling`, `truncate`, `round`
|
274
|
-
* Integer-level: `even?`, `odd?`, `integer->char`
|
275
|
-
|
276
|
-
#### List procedures
|
277
|
-
* `list?`, `null?`, `pair?`, `append`, `car`, `cdr`, `caar`, `cadr`, `cdar`, `cddr`, `cons`, `length`, `list`, `list-copy`, `list->vector`, `reverse`, `set-car!`, `set-cdr!`
|
278
|
-
, `assq`, `assv`
|
279
|
-
|
280
|
-
#### String procedures
|
281
|
-
* `string?`, `string=?`, `string`, `make-string`, `string-append`, `string-length`, `string->symbol`
|
282
353
|
|
283
|
-
|
284
|
-
* `symbol?`, `symbol=?`, `symbol->string`
|
285
|
-
|
286
|
-
#### Vector procedures
|
287
|
-
* `vector?`, `make-vector`, `vector`, `vector-length`, `vector-set!`, `vector->list`
|
288
|
-
|
289
|
-
#### Control procedures
|
290
|
-
* `procedure?`, `apply`, `map`
|
291
|
-
|
292
|
-
#### Input/output procedures
|
293
|
-
* `newline`
|
294
|
-
|
295
|
-
#### Special procedures
|
296
|
-
* `assert`
|
297
|
-
|
298
|
-
Roadmap:
|
299
|
-
- Extend language support
|
300
|
-
- Implement REPL
|
354
|
+
## Roadmap
|
301
355
|
- Implement an equivalent of [lis.py](http://www.norvig.com/lispy.html)
|
302
356
|
- Implement an equivalent of [lispy](http://norvig.com/lispy2.html)
|
303
357
|
- Make it pass the test suite
|
304
358
|
- Extend the language in order to support [Minikanren](https://github.com/TheReasonedSchemer2ndEd/CodeFromTheReasonedSchemer2ndEd)
|
305
359
|
- Make it pass all examples from the [Reasoned Schemer](https://mitpress.mit.edu/books/reasoned-schemer-second-edition) book.
|
306
360
|
|
361
|
+
## About Scheme
|
362
|
+
|
363
|
+
The Scheme programming language is a Lisp dialect that supports multiple paradigms, including functional programming and imperative programming.
|
364
|
+
|
365
|
+
### Resources on Scheme
|
366
|
+
Here are a few pointers for the Scheme programming language:
|
367
|
+
- Wikipedia article on [Scheme](https://en.m.wikipedia.org/wiki/Scheme_\(programming_language\))
|
368
|
+
- Latest official Scheme standard: [R7RS](https://bitbucket.org/cowan/r7rs-wg1-infra/src/default/R7RSHomePage.md)
|
369
|
+
#### Online tutorials and books:
|
370
|
+
- [The Scheme Programming Language, 4th Edition](https://www.scheme.com/tspl4/) by Kent Dybvig. A complete, introductory textbook on Scheme based on the older R5RS standard.
|
371
|
+
- [Teach Yourself Scheme in Fixnum Days](http://ds26gte.github.io/tyscheme/index.html) by Dorai Sitaram
|
372
|
+
- [Yet Another Scheme Tutorial](http://www.shido.info/lisp/idx_scm_e.html) by Shido Takafumi
|
373
|
+
- [An Introduction to Scheme and its Implementation](http://www.cs.utexas.edu/ftp/garbage/cs345/schintro-v14/schintro_toc.html) by Paul R. Wilson
|
374
|
+
|
375
|
+
|
307
376
|
## Other Scheme implementations in Ruby
|
308
377
|
__Skeem__ isn't the sole implementation of the Scheme language in Ruby.
|
309
378
|
Here are a few other ones:
|
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/cubic.skm
ADDED
data/bin/hello-world.skm
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
(display "Hello, world")
|
data/bin/skeem
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'skeem'
|
5
|
+
|
6
|
+
class SkeemREPL
|
7
|
+
attr_reader :interpreter
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@interpreter = Skeem::Interpreter.new
|
11
|
+
end
|
12
|
+
|
13
|
+
def run_session
|
14
|
+
puts "Welcome to Skeem #{Skeem::VERSION}."
|
15
|
+
loop do
|
16
|
+
print '> '
|
17
|
+
input = gets.chomp.strip
|
18
|
+
break if %w[(quit) (exit)].include?(input)
|
19
|
+
|
20
|
+
process_input(input)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def run_file(aFilename)
|
25
|
+
if File.exist?(aFilename)
|
26
|
+
valid_fname = aFilename
|
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
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
raise ScriptError, "No such file -- #{aFilename}" unless valid_fname
|
38
|
+
|
39
|
+
source_code = File.read(valid_fname)
|
40
|
+
process_input(source_code)
|
41
|
+
end
|
42
|
+
|
43
|
+
def process_input(input)
|
44
|
+
begin
|
45
|
+
ptree = interpreter.parse(input)
|
46
|
+
rescue StandardError => e
|
47
|
+
$stderr.puts e.message
|
48
|
+
return
|
49
|
+
end
|
50
|
+
|
51
|
+
raw_result = ptree.root.evaluate(interpreter.runtime)
|
52
|
+
result = raw_result.kind_of?(Skeem::SkmPair) ? raw_result.last : raw_result
|
53
|
+
if result.kind_of?(Skeem::SkmUndefined)
|
54
|
+
puts "\n#{result.class}"
|
55
|
+
elsif result.respond_to?(:value)
|
56
|
+
puts result.value
|
57
|
+
else
|
58
|
+
puts result.inspect
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end # class
|
62
|
+
|
63
|
+
########################################
|
64
|
+
# Entry point
|
65
|
+
########################################
|
66
|
+
djinn = SkeemREPL.new
|
67
|
+
|
68
|
+
if ARGV.empty?
|
69
|
+
djinn.run_session
|
70
|
+
else
|
71
|
+
djinn.run_file(ARGV[0])
|
72
|
+
end
|
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'
|
@@ -9,7 +11,7 @@ module Skeem
|
|
9
11
|
def boolean(aBoolean)
|
10
12
|
return aBoolean if aBoolean.kind_of?(SkmBoolean)
|
11
13
|
|
12
|
-
|
14
|
+
case aBoolean
|
13
15
|
when TrueClass, FalseClass
|
14
16
|
SkmBoolean.create(aBoolean)
|
15
17
|
when /^#t(?:rue)?|true$/
|
@@ -24,7 +26,7 @@ module Skeem
|
|
24
26
|
def integer(aLiteral)
|
25
27
|
return aLiteral if aLiteral.kind_of?(SkmInteger)
|
26
28
|
|
27
|
-
|
29
|
+
case aLiteral
|
28
30
|
when Integer
|
29
31
|
SkmInteger.create(aLiteral)
|
30
32
|
when /^[+-]?\d+$/
|
@@ -37,7 +39,7 @@ module Skeem
|
|
37
39
|
def rational(aLiteral)
|
38
40
|
return aLiteral if aLiteral.kind_of?(SkmRational)
|
39
41
|
|
40
|
-
|
42
|
+
case aLiteral
|
41
43
|
when Rational
|
42
44
|
SkmRational.create(aLiteral)
|
43
45
|
when /^[+-]?\d+\/\d+$/
|
@@ -50,7 +52,7 @@ module Skeem
|
|
50
52
|
def real(aLiteral)
|
51
53
|
return aLiteral if aLiteral.kind_of?(SkmReal)
|
52
54
|
|
53
|
-
|
55
|
+
case aLiteral
|
54
56
|
when Numeric
|
55
57
|
SkmReal.create(aLiteral)
|
56
58
|
when /^[+-]?\d+(?:\.\d*)?(?:[eE][+-]?\d+)?$/
|
@@ -63,7 +65,7 @@ module Skeem
|
|
63
65
|
def char(aLiteral)
|
64
66
|
return aLiteral if aLiteral.kind_of?(SkmChar)
|
65
67
|
|
66
|
-
|
68
|
+
case aLiteral
|
67
69
|
when Numeric
|
68
70
|
SkmChar.create_from_int(aLiteral)
|
69
71
|
when String
|
@@ -80,7 +82,7 @@ module Skeem
|
|
80
82
|
def string(aLiteral)
|
81
83
|
return aLiteral if aLiteral.kind_of?(SkmString)
|
82
84
|
|
83
|
-
|
85
|
+
case aLiteral
|
84
86
|
when String
|
85
87
|
SkmString.create(aLiteral)
|
86
88
|
when SkmIdentifier
|
@@ -93,7 +95,7 @@ module Skeem
|
|
93
95
|
def identifier(aLiteral)
|
94
96
|
return aLiteral if aLiteral.kind_of?(SkmIdentifier)
|
95
97
|
|
96
|
-
|
98
|
+
case aLiteral
|
97
99
|
when String
|
98
100
|
SkmIdentifier.create(aLiteral)
|
99
101
|
when SkmString
|
@@ -106,7 +108,7 @@ module Skeem
|
|
106
108
|
alias symbol identifier
|
107
109
|
|
108
110
|
def list(aLiteral)
|
109
|
-
|
111
|
+
case aLiteral
|
110
112
|
when Array
|
111
113
|
SkmPair.create_from_a(to_datum(aLiteral))
|
112
114
|
when SkmPair
|
@@ -114,12 +116,10 @@ module Skeem
|
|
114
116
|
else
|
115
117
|
SkmPair.new(to_datum(aLiteral), SkmEmptyList.instance)
|
116
118
|
end
|
117
|
-
|
118
|
-
result
|
119
119
|
end
|
120
120
|
|
121
121
|
def vector(aLiteral)
|
122
|
-
|
122
|
+
case aLiteral
|
123
123
|
when Array
|
124
124
|
SkmVector.new(to_datum(aLiteral))
|
125
125
|
when SkmVector
|
@@ -127,8 +127,6 @@ module Skeem
|
|
127
127
|
else
|
128
128
|
SkmVector.new([to_datum(aLiteral)])
|
129
129
|
end
|
130
|
-
|
131
|
-
result
|
132
130
|
end
|
133
131
|
|
134
132
|
# Conversion from Ruby object value to Skeem datum
|
@@ -137,7 +135,7 @@ module Skeem
|
|
137
135
|
return vector(aLiteral.members) if aLiteral.kind_of?(SkmVector)
|
138
136
|
return aLiteral if aLiteral.kind_of?(Primitive::PrimitiveProcedure)
|
139
137
|
|
140
|
-
|
138
|
+
case aLiteral
|
141
139
|
when Array
|
142
140
|
aLiteral.map { |elem| to_datum(elem) }
|
143
141
|
when Integer
|
@@ -150,33 +148,45 @@ module Skeem
|
|
150
148
|
SkmBoolean.create(aLiteral)
|
151
149
|
when String
|
152
150
|
parse_literal(aLiteral)
|
153
|
-
when SkmPair
|
151
|
+
when SkmPair # Special case: not a PORO literal
|
154
152
|
# One assumes that a Skeem list contains only Skeem datum objects
|
155
153
|
SkmPair.create_from_a(aLiteral.to_a)
|
156
154
|
when SkmUndefined
|
157
155
|
aLiteral
|
158
156
|
else
|
159
157
|
raise StandardError, aLiteral.inspect
|
160
|
-
|
158
|
+
end
|
161
159
|
end
|
162
160
|
|
163
161
|
private
|
164
162
|
|
165
163
|
def parse_literal(aLiteral)
|
166
|
-
if aLiteral =~ /^#t(?:rue)?|true$/
|
167
|
-
boolean(aLiteral)
|
168
|
-
elsif aLiteral =~ /^#f(?:alse)?|false$/
|
169
|
-
boolean(aLiteral)
|
170
|
-
elsif aLiteral =~ /^[+-]?\d+\/\d+$/
|
171
|
-
rational(aLiteral)
|
172
|
-
elsif aLiteral =~ /^[+-]?\d+$/
|
173
|
-
integer(aLiteral)
|
174
|
-
elsif aLiteral =~ /^[+-]?\d+(?:\.\d*)?(?:[eE][+-]?\d+)?$/
|
175
|
-
real(aLiteral)
|
176
|
-
else
|
177
|
-
string(aLiteral)
|
164
|
+
# if aLiteral =~ /^#t(?:rue)?|true$/
|
165
|
+
# boolean(aLiteral)
|
166
|
+
# elsif aLiteral =~ /^#f(?:alse)?|false$/
|
167
|
+
# boolean(aLiteral)
|
168
|
+
# elsif aLiteral =~ /^[+-]?\d+\/\d+$/
|
169
|
+
# rational(aLiteral)
|
170
|
+
# elsif aLiteral =~ /^[+-]?\d+$/
|
171
|
+
# integer(aLiteral)
|
172
|
+
# elsif aLiteral =~ /^[+-]?\d+(?:\.\d*)?(?:[eE][+-]?\d+)?$/
|
173
|
+
# real(aLiteral)
|
174
|
+
# else
|
175
|
+
# string(aLiteral)
|
176
|
+
# end
|
177
|
+
|
178
|
+
case aLiteral
|
179
|
+
when /^#t(?:rue)?|true$/, /^#f(?:alse)?|false$/
|
180
|
+
boolean(aLiteral)
|
181
|
+
when /^[+-]?\d+\/\d+$/
|
182
|
+
rational(aLiteral)
|
183
|
+
when /^[+-]?\d+$/
|
184
|
+
integer(aLiteral)
|
185
|
+
when /^[+-]?\d+(?:\.\d*)?(?:[eE][+-]?\d+)?$/
|
186
|
+
real(aLiteral)
|
187
|
+
else
|
188
|
+
string(aLiteral)
|
178
189
|
end
|
179
190
|
end
|
180
|
-
|
181
191
|
end # module
|
182
|
-
end # module
|
192
|
+
end # module
|