skeem 0.2.14 → 0.2.18
Sign up to get free protection for your applications and to get access to all the features.
- 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
|