skeem 0.2.12 → 0.2.13
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/CHANGELOG.md +14 -0
- data/README.md +4 -4
- data/lib/skeem/datum_dsl.rb +19 -2
- data/lib/skeem/grammar.rb +1 -0
- data/lib/skeem/primitive/primitive_builder.rb +83 -1
- data/lib/skeem/skm_simple_datum.rb +8 -1
- data/lib/skeem/tokenizer.rb +25 -7
- data/lib/skeem/version.rb +1 -1
- data/spec/skeem/primitive/primitive_builder_spec.rb +90 -0
- data/spec/skeem/tokenizer_spec.rb +27 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 56bd360c4a30ba9dae003a18c922b150924fd0471fe74f1196e75967161ed767
|
4
|
+
data.tar.gz: 90a2af34b4aa7b327656d7f889c94cead17d7a906d5db36e31d7a4ab3af5e920
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 87827300a4e54068a2e885ef74b5aba42d21d3639a933cb4060b02b39f55b74cc15697098134ca341b1c1bceb6c027c67e1b113de9c10d4455f3b3fed0e0f009
|
7
|
+
data.tar.gz: 3875d43e7c46826a7b6246f5ea07da250401281d54479bb933e0fe73b3da610ac43e1104bdacf975ad658d1ef2834a34a895b24142545cb201b59e028ad5aaa9
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
## [0.2.13] - 2019-06-22
|
2
|
+
- Skeem now accepts integers in hexadecimal notation
|
3
|
+
- Added procedures: `char->integer`, `integer->char`, `char=?`, `char<?`, `char>?`, `char<=?`, `char>=?`
|
4
|
+
|
5
|
+
### Changed
|
6
|
+
- Class Tokenizer updated to recognize integer literals in hexadecimal notation.
|
7
|
+
- `DatumDSL#char(aLiteral): added conversion of char literal into SkmChar.
|
8
|
+
- File `grammar.rb` Added a rule to derive a simple datum from a character literal
|
9
|
+
- File `primitive_builder.rb` Implemented primitive procedures `char->integer`, `integer->char`, `char=?`, `char<?`, `char>?`, `char<=?`, `char>=?`
|
10
|
+
- File `README.md` Added mentions to new procedures.
|
11
|
+
- File `tokenize_spec.rb: added tests for haxadecimal integers.
|
12
|
+
- File `primitive_builder_spec.rb`: Added tests for new procedures.
|
13
|
+
|
14
|
+
|
1
15
|
## [0.2.12] - 2019-06-19
|
2
16
|
- Skeem now supports character datatype
|
3
17
|
- Added procedures: `boolean=?`, `char?`, `string`, `make-string`, `reverse`
|
data/README.md
CHANGED
@@ -176,7 +176,7 @@ Here are a few pointers for the Scheme programming language:
|
|
176
176
|
- Of the number hierarchy:
|
177
177
|
`real` (e.g. 2.718, 6.671e-11),
|
178
178
|
`rational` (e.g. 22/7, 1/137, -13/41)
|
179
|
-
`integer` (42, -3)
|
179
|
+
`integer` (42, -3 also in hexadecimal notation: #x3af)
|
180
180
|
- Lists (quoted) : '(1 two "three")
|
181
181
|
- Strings: `"Hello, world."`
|
182
182
|
- Identifiers (symbols): `really-cool-procedure`
|
@@ -249,17 +249,17 @@ This section lists the implemented standard procedures
|
|
249
249
|
* `eqv?`, `equal?`
|
250
250
|
|
251
251
|
#### Boolean procedures
|
252
|
-
* `boolean?`, `and`, `or`, `not`
|
252
|
+
* `boolean?`, `boolean=?`, `and`, `or`, `not`
|
253
253
|
|
254
254
|
#### Character procedures
|
255
|
-
* `char?`
|
255
|
+
* `char?` `char->integer`, `char=?`, `char<?`, `char>?`,`char<=?`, `char>=?`
|
256
256
|
|
257
257
|
#### Numerical operations
|
258
258
|
* Number-level: `number?`, `complex?`, `real?`, `rational?`, `integer?`, `zero?`, `exact?`, `inexact?`, `exact-integer?` , `+`, `-`, `*`, `/`,
|
259
259
|
`=`, `square`, `number->string`
|
260
260
|
* Real-level: `positive?`, `negative?`, `<`, `>`, `<=`, `>=`, `abs`, `max`, `min`, `floor/`, `floor-quotient`, `floor-remainder`, `truncate/`, `truncate-quotient`,
|
261
261
|
`truncate-remainder`, `quotient`, `remainder`, `modulo`, `gcd`, `lcm`, `numerator`, `denominator`, `floor`, `ceiling`, `truncate`, `round`
|
262
|
-
* Integer-level: `even?`, `odd
|
262
|
+
* Integer-level: `even?`, `odd?`, `integer->char`
|
263
263
|
|
264
264
|
#### List procedures
|
265
265
|
* `list?`, `null?`, `pair?`, `append`, `car`, `cdr`, `caar`, `cadr`, `cdar`, `cddr`, `cons`, `length`, `list`, `list-copy`, `list->vector`, `reverse`, `set-car!`, `set-cdr!`
|
data/lib/skeem/datum_dsl.rb
CHANGED
@@ -33,7 +33,7 @@ module Skeem
|
|
33
33
|
raise StandardError, aLiteral.inspect
|
34
34
|
end
|
35
35
|
end
|
36
|
-
|
36
|
+
|
37
37
|
def rational(aLiteral)
|
38
38
|
return aLiteral if aLiteral.kind_of?(SkmRational)
|
39
39
|
|
@@ -45,7 +45,7 @@ module Skeem
|
|
45
45
|
else
|
46
46
|
raise StandardError, aLiteral.inspect
|
47
47
|
end
|
48
|
-
end
|
48
|
+
end
|
49
49
|
|
50
50
|
def real(aLiteral)
|
51
51
|
return aLiteral if aLiteral.kind_of?(SkmReal)
|
@@ -60,6 +60,23 @@ module Skeem
|
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
63
|
+
def char(aLiteral)
|
64
|
+
return aLiteral if aLiteral.kind_of?(SkmChar)
|
65
|
+
|
66
|
+
result = case aLiteral
|
67
|
+
when Numeric
|
68
|
+
SkmChar.create_from_int(aLiteral)
|
69
|
+
when String
|
70
|
+
value = aLiteral.empty? ? '' : aLiteral.chr
|
71
|
+
SkmChar.create(value)
|
72
|
+
when SkmString
|
73
|
+
value = aLiteral.value.empty? ? '' : aLiteral.value.chr
|
74
|
+
SkmChar.create(value)
|
75
|
+
else
|
76
|
+
raise StandardError, aLiteral.inspect
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
63
80
|
def string(aLiteral)
|
64
81
|
return aLiteral if aLiteral.kind_of?(SkmString)
|
65
82
|
|
data/lib/skeem/grammar.rb
CHANGED
@@ -95,6 +95,13 @@ module Skeem
|
|
95
95
|
|
96
96
|
def add_char_procedures(aRuntime)
|
97
97
|
create_object_predicate(aRuntime, 'char?')
|
98
|
+
create_char2int(aRuntime)
|
99
|
+
create_int2char(aRuntime)
|
100
|
+
create_char_equal(aRuntime)
|
101
|
+
create_char_lt(aRuntime)
|
102
|
+
create_char_gt(aRuntime)
|
103
|
+
create_char_lte(aRuntime)
|
104
|
+
create_char_gte(aRuntime)
|
98
105
|
end
|
99
106
|
|
100
107
|
def add_string_procedures(aRuntime)
|
@@ -572,14 +579,89 @@ module Skeem
|
|
572
579
|
end
|
573
580
|
end
|
574
581
|
|
582
|
+
# Return true, if all arguments are monotonously increasing
|
583
|
+
def compare_all(first_operand, arglist, operation)
|
584
|
+
if arglist.empty?
|
585
|
+
result = true
|
586
|
+
else
|
587
|
+
result = first_operand.value.send(operation, arglist[0].value)
|
588
|
+
if result
|
589
|
+
arglist.each_cons(2) do |(operand1, operand2)|
|
590
|
+
value1 = operand1.value
|
591
|
+
result &&= value1.send(operation, operand2.value)
|
592
|
+
end
|
593
|
+
end
|
594
|
+
end
|
595
|
+
boolean(result)
|
596
|
+
end
|
597
|
+
|
575
598
|
def create_boolean_equal(aRuntime)
|
576
599
|
primitive = ->(_runtime, first_operand, arglist) do
|
577
|
-
|
600
|
+
compare_all(first_operand, arglist, :==)
|
578
601
|
end
|
579
602
|
|
580
603
|
define_primitive_proc(aRuntime, 'boolean=?', one_or_more, primitive)
|
581
604
|
end
|
582
605
|
|
606
|
+
def create_char2int(aRuntime)
|
607
|
+
primitive = ->(runtime, arg_evaluated) do
|
608
|
+
check_argtype(arg_evaluated, SkmChar, 'character', 'char->integer')
|
609
|
+
integer(arg_evaluated.value.ord)
|
610
|
+
end
|
611
|
+
|
612
|
+
define_primitive_proc(aRuntime, 'char->integer', unary, primitive)
|
613
|
+
end
|
614
|
+
|
615
|
+
def create_int2char(aRuntime)
|
616
|
+
primitive = ->(runtime, arg_evaluated) do
|
617
|
+
check_argtype(arg_evaluated, SkmInteger, 'integer', 'integer->char')
|
618
|
+
char(arg_evaluated.value.ord)
|
619
|
+
end
|
620
|
+
|
621
|
+
define_primitive_proc(aRuntime, 'integer->char', unary, primitive)
|
622
|
+
end
|
623
|
+
|
624
|
+
def create_char_equal(aRuntime)
|
625
|
+
primitive = ->(_runtime, first_operand, arglist) do
|
626
|
+
compare_all(first_operand, arglist, :==)
|
627
|
+
end
|
628
|
+
|
629
|
+
define_primitive_proc(aRuntime, 'char=?', one_or_more, primitive)
|
630
|
+
end
|
631
|
+
|
632
|
+
def create_char_lt(aRuntime)
|
633
|
+
primitive = ->(_runtime, first_operand, arglist) do
|
634
|
+
compare_all(first_operand, arglist, :<)
|
635
|
+
end
|
636
|
+
|
637
|
+
define_primitive_proc(aRuntime, 'char<?', one_or_more, primitive)
|
638
|
+
end
|
639
|
+
|
640
|
+
def create_char_gt(aRuntime)
|
641
|
+
primitive = ->(_runtime, first_operand, arglist) do
|
642
|
+
compare_all(first_operand, arglist, :>)
|
643
|
+
end
|
644
|
+
|
645
|
+
define_primitive_proc(aRuntime, 'char>?', one_or_more, primitive)
|
646
|
+
end
|
647
|
+
|
648
|
+
def create_char_lte(aRuntime)
|
649
|
+
primitive = ->(_runtime, first_operand, arglist) do
|
650
|
+
compare_all(first_operand, arglist, :<=)
|
651
|
+
end
|
652
|
+
|
653
|
+
define_primitive_proc(aRuntime, 'char<=?', one_or_more, primitive)
|
654
|
+
end
|
655
|
+
|
656
|
+
def create_char_gte(aRuntime)
|
657
|
+
primitive = ->(_runtime, first_operand, arglist) do
|
658
|
+
compare_all(first_operand, arglist, :>=)
|
659
|
+
end
|
660
|
+
|
661
|
+
define_primitive_proc(aRuntime, 'char>=?', one_or_more, primitive)
|
662
|
+
end
|
663
|
+
|
664
|
+
|
583
665
|
def create_make_string(aRuntime)
|
584
666
|
primitive = ->(runtime, count_arg, arglist) do
|
585
667
|
count = count_arg
|
@@ -152,7 +152,14 @@ module Skeem
|
|
152
152
|
class SkmChar < SkmSimpleDatum
|
153
153
|
def char?
|
154
154
|
true
|
155
|
-
end
|
155
|
+
end
|
156
|
+
|
157
|
+
def self.create_from_int(anInteger)
|
158
|
+
int_value = anInteger.kind_of?(SkmInteger) ? anInteger.value : anInteger
|
159
|
+
char_value = int_value < 0xff ? int_value.chr : [int_value].pack('U')
|
160
|
+
create(char_value)
|
161
|
+
end
|
162
|
+
|
156
163
|
end # class
|
157
164
|
|
158
165
|
class SkmString < SkmSimpleDatum
|
data/lib/skeem/tokenizer.rb
CHANGED
@@ -93,15 +93,17 @@ module Skeem
|
|
93
93
|
token = build_token(@@lexeme2name[lexeme], lexeme)
|
94
94
|
elsif (token = recognize_char_token)
|
95
95
|
# Do nothing
|
96
|
-
elsif (lexeme = scanner.scan(/#(?:(?:true)|(?:false)|(?:u8)|[\\\(tfeiodx]|(?:\d+[=#]))/))
|
97
|
-
token = cardinal_token(lexeme)
|
98
96
|
elsif (lexeme = scanner.scan(/[+-]?[0-9]+\/[0-9]+(?=\s|[|()";]|$)/))
|
99
97
|
token = build_token('RATIONAL', lexeme) # Decimal radix
|
100
|
-
elsif (lexeme = scanner.scan(/[+-]?[0-9]+(?:.0+)?(?=\s|[|()";]|$)/))
|
98
|
+
elsif (lexeme = scanner.scan(/(?:#[dD])?[+-]?[0-9]+(?:.0+)?(?=\s|[|()";]|$)/))
|
101
99
|
token = build_token('INTEGER', lexeme) # Decimal radix
|
100
|
+
elsif (lexeme = scanner.scan(/#[xX][+-]?[0-9a-fA-F]+(?=\s|[|()";]|$)/))
|
101
|
+
token = build_token('INTEGER', lexeme) # Hexadecimal radix
|
102
102
|
elsif (lexeme = scanner.scan(/[+-]?[0-9]+(?:\.[0-9]*)?(?:(?:e|E)[+-]?[0-9]+)?/))
|
103
103
|
# Order dependency: must be tested after INTEGER case
|
104
104
|
token = build_token('REAL', lexeme)
|
105
|
+
elsif (lexeme = scanner.scan(/#(?:(?:true)|(?:false)|(?:u8)|[\\\(tfeiodx]|(?:\d+[=#]))/))
|
106
|
+
token = cardinal_token(lexeme)
|
105
107
|
elsif (lexeme = scanner.scan(/"(?:\\"|[^"])*"/)) # Double quotes literal?
|
106
108
|
token = build_token('STRING_LIT', lexeme)
|
107
109
|
elsif (lexeme = scanner.scan(/[a-zA-Z!$%&*\/:<=>?@^_~][a-zA-Z0-9!$%&*+-.\/:<=>?@^_~+-]*/))
|
@@ -136,7 +138,6 @@ Bytevector constants are terminated by ) .
|
|
136
138
|
numbers (section 6.2.5).
|
137
139
|
#<n>= #<n># These are used for labeling and referencing
|
138
140
|
other literal data (section 2.4).
|
139
|
-
# token = build_token('BOOLEAN', lexeme)
|
140
141
|
=end
|
141
142
|
def cardinal_token(aLexeme)
|
142
143
|
case aLexeme
|
@@ -210,9 +211,26 @@ other literal data (section 2.4).
|
|
210
211
|
end
|
211
212
|
|
212
213
|
def to_integer(aLexeme, aFormat)
|
213
|
-
|
214
|
-
|
215
|
-
|
214
|
+
literal = aLexeme.downcase
|
215
|
+
prefix_pattern = /^#[dx]/
|
216
|
+
matching = literal.match(prefix_pattern)
|
217
|
+
if matching
|
218
|
+
case matching[0]
|
219
|
+
when '#d'
|
220
|
+
format = :base10
|
221
|
+
when '#x'
|
222
|
+
format = :base16
|
223
|
+
end
|
224
|
+
literal = matching.post_match
|
225
|
+
else
|
226
|
+
format = :default
|
227
|
+
end
|
228
|
+
|
229
|
+
case format
|
230
|
+
when :default, :base10
|
231
|
+
value = literal.to_i
|
232
|
+
when :base16
|
233
|
+
value = literal.to_i(16)
|
216
234
|
end
|
217
235
|
|
218
236
|
value
|
data/lib/skeem/version.rb
CHANGED
@@ -755,6 +755,96 @@ SKEEM
|
|
755
755
|
end
|
756
756
|
end # context
|
757
757
|
|
758
|
+
context 'Character procedures:' do
|
759
|
+
it 'should implement the char? procedure' do
|
760
|
+
checks = [
|
761
|
+
['(char? #f)', false],
|
762
|
+
["(char? 'a)", false],
|
763
|
+
['(char? #\a)', true],
|
764
|
+
['(char? "a")', false],
|
765
|
+
["(char? '(#\\a 1))", false]
|
766
|
+
]
|
767
|
+
compare_to_predicted(checks)
|
768
|
+
end
|
769
|
+
|
770
|
+
it 'should implement the char->integer procedure' do
|
771
|
+
checks = [
|
772
|
+
['(char->integer #\space)', 0x20],
|
773
|
+
['(char->integer #\newline)', 0x0a],
|
774
|
+
['(char->integer #\a)', ?a.ord],
|
775
|
+
['(char->integer #\x05a)', 0x5a]
|
776
|
+
]
|
777
|
+
compare_to_predicted(checks)
|
778
|
+
end
|
779
|
+
|
780
|
+
it 'should implement the integer->char procedure' do
|
781
|
+
checks = [
|
782
|
+
['(integer->char #x20)', ?\s],
|
783
|
+
['(integer->char 48)', ?0],
|
784
|
+
['(integer->char #x0a)', ?\n],
|
785
|
+
['(integer->char #x3bb)', ?\u03bb]
|
786
|
+
]
|
787
|
+
compare_to_predicted(checks)
|
788
|
+
end
|
789
|
+
|
790
|
+
it 'should implement the char=? procedure' do
|
791
|
+
checks = [
|
792
|
+
['(char=? #\a)', true],
|
793
|
+
['(char=? #\a #\a)', true],
|
794
|
+
['(char=? #\a #\b)', false],
|
795
|
+
['(char=? #\space #\space #\space)', true],
|
796
|
+
['(char=? #\space #\space #\newline)', false]
|
797
|
+
]
|
798
|
+
compare_to_predicted(checks)
|
799
|
+
end
|
800
|
+
|
801
|
+
it 'should implement the char<? procedure' do
|
802
|
+
checks = [
|
803
|
+
['(char<? #\a)', true],
|
804
|
+
['(char<? #\a #\a)', false],
|
805
|
+
['(char<? #\a #\b)', true],
|
806
|
+
['(char<? #\a #\b #\c)', true],
|
807
|
+
['(char<? #\a #\c #\b)', false]
|
808
|
+
]
|
809
|
+
compare_to_predicted(checks)
|
810
|
+
end
|
811
|
+
|
812
|
+
it 'should implement the char>? procedure' do
|
813
|
+
checks = [
|
814
|
+
['(char>? #\b)', true],
|
815
|
+
['(char>? #\b #\b)', false],
|
816
|
+
['(char>? #\b #\a)', true],
|
817
|
+
['(char>? #\c #\b #\a)', true],
|
818
|
+
['(char>? #\c #\a #\b)', false]
|
819
|
+
]
|
820
|
+
compare_to_predicted(checks)
|
821
|
+
end
|
822
|
+
|
823
|
+
it 'should implement the char<=? procedure' do
|
824
|
+
checks = [
|
825
|
+
['(char<=? #\a)', true],
|
826
|
+
['(char<=? #\a #\a)', true],
|
827
|
+
['(char<=? #\b #\a)', false],
|
828
|
+
['(char<=? #\a #\b #\c)', true],
|
829
|
+
['(char<=? #\a #\c #\c)', true],
|
830
|
+
['(char<=? #\a #\c #\b)', false]
|
831
|
+
]
|
832
|
+
compare_to_predicted(checks)
|
833
|
+
end
|
834
|
+
|
835
|
+
it 'should implement the char>=? procedure' do
|
836
|
+
checks = [
|
837
|
+
['(char>=? #\a)', true],
|
838
|
+
['(char>=? #\a #\a)', true],
|
839
|
+
['(char>=? #\a #\b)', false],
|
840
|
+
['(char>=? #\c #\b #\a)', true],
|
841
|
+
['(char>=? #\c #\b #\b)', true],
|
842
|
+
['(char>=? #\c #\a #\b)', false]
|
843
|
+
]
|
844
|
+
compare_to_predicted(checks)
|
845
|
+
end
|
846
|
+
end # context
|
847
|
+
|
758
848
|
context 'Vector procedures:' do
|
759
849
|
it 'should implement the vector? procedure' do
|
760
850
|
checks = [
|
@@ -80,6 +80,33 @@ module Skeem
|
|
80
80
|
|
81
81
|
check_tokens(tests, 'INTEGER')
|
82
82
|
end
|
83
|
+
|
84
|
+
it 'should tokenize integers with explicit radix 10' do
|
85
|
+
tests = [
|
86
|
+
# couple [raw input, expected]
|
87
|
+
['#d0', 0],
|
88
|
+
['#D3', 3],
|
89
|
+
['#d+3 ', +3],
|
90
|
+
['#D-3', -3],
|
91
|
+
['#d-3.0', -3],
|
92
|
+
['#D-1234', -1234]
|
93
|
+
]
|
94
|
+
|
95
|
+
check_tokens(tests, 'INTEGER')
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'should tokenize integers in hexadecimal notation' do
|
99
|
+
tests = [
|
100
|
+
# couple [raw input, expected]
|
101
|
+
['#x0', 0],
|
102
|
+
['#Xf', 0xf],
|
103
|
+
['#x+F ', 0xf],
|
104
|
+
['#X-f', -0xf],
|
105
|
+
['#X-12Ac', -0x12ac]
|
106
|
+
]
|
107
|
+
|
108
|
+
check_tokens(tests, 'INTEGER')
|
109
|
+
end
|
83
110
|
end # context
|
84
111
|
|
85
112
|
context 'Rational literals recognition:' do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: skeem
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.13
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dimitri Geshef
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-06-
|
11
|
+
date: 2019-06-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rley
|