Skip to content

Commit 172012b

Browse files
committed
Add integer type and fix natural_number
Strings which merely contained digits were assignable to `natural_number`. Oops!
1 parent 51b80a3 commit 172012b

File tree

2 files changed

+40
-4
lines changed

2 files changed

+40
-4
lines changed

src/language/semantics/type-system.test.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { testCases } from '../../test-utilities.test.js'
22
import {
33
boolean,
44
functionType,
5+
integer,
56
naturalNumber,
67
nothing,
78
nullType,
@@ -90,6 +91,7 @@ typeAssignabilitySuite('prelude types (assignable)', [
9091
[[nullType, nullType], true],
9192
[[boolean, boolean], true],
9293
[[naturalNumber, naturalNumber], true],
94+
[[integer, integer], true],
9395
[[string, string], true],
9496
[[object, object], true],
9597
[[functionType, functionType], true],
@@ -104,8 +106,11 @@ typeAssignabilitySuite('prelude types (assignable)', [
104106
[[nullType, something], true],
105107
[[boolean, string], true],
106108
[[boolean, something], true],
109+
[[naturalNumber, integer], true],
107110
[[naturalNumber, string], true],
108111
[[naturalNumber, something], true],
112+
[[integer, string], true],
113+
[[integer, something], true],
109114
[[string, something], true],
110115
[[object, something], true],
111116
[[functionType, something], true],
@@ -115,35 +120,52 @@ typeAssignabilitySuite('prelude types (not assignable)', [
115120
[[nullType, nothing], false],
116121
[[nullType, boolean], false],
117122
[[nullType, naturalNumber], false],
123+
[[nullType, integer], false],
118124
[[nullType, object], false],
119125
[[nullType, functionType], false],
120126
[[boolean, nothing], false],
121127
[[boolean, nullType], false],
122128
[[boolean, naturalNumber], false],
129+
[[boolean, integer], false],
123130
[[boolean, object], false],
124131
[[boolean, functionType], false],
132+
[[naturalNumber, nothing], false],
133+
[[naturalNumber, nullType], false],
134+
[[naturalNumber, boolean], false],
135+
[[naturalNumber, object], false],
136+
[[naturalNumber, functionType], false],
137+
[[integer, nothing], false],
138+
[[integer, nullType], false],
139+
[[integer, boolean], false],
140+
[[integer, naturalNumber], false],
141+
[[integer, object], false],
142+
[[integer, functionType], false],
125143
[[string, nothing], false],
126144
[[string, nullType], false],
127145
[[string, boolean], false],
128146
[[string, naturalNumber], false],
147+
[[string, integer], false],
129148
[[string, object], false],
130149
[[string, functionType], false],
131150
[[object, nothing], false],
132151
[[object, nullType], false],
133152
[[object, boolean], false],
134153
[[object, naturalNumber], false],
154+
[[object, integer], false],
135155
[[object, string], false],
136156
[[object, functionType], false],
137157
[[functionType, nothing], false],
138158
[[functionType, nullType], false],
139159
[[functionType, boolean], false],
140160
[[functionType, naturalNumber], false],
161+
[[functionType, integer], false],
141162
[[functionType, string], false],
142163
[[functionType, object], false],
143164
[[something, nothing], false],
144165
[[something, nullType], false],
145166
[[something, boolean], false],
146167
[[something, naturalNumber], false],
168+
[[something, integer], false],
147169
[[something, string], false],
148170
[[something, object], false],
149171
[[something, functionType], false],
@@ -154,7 +176,6 @@ typeAssignabilitySuite('custom types (assignable)', [
154176
[[makeUnionType('', ['a']), string], true],
155177
[[makeUnionType('', ['a', 'b']), string], true],
156178
[[makeUnionType('', ['a']), makeUnionType('', [string, 'b'])], true],
157-
158179
[[makeUnionType('', ['1']), naturalNumber], true],
159180
[[makeUnionType('', ['0', '1']), naturalNumber], true],
160181
[
@@ -164,6 +185,7 @@ typeAssignabilitySuite('custom types (assignable)', [
164185
],
165186
true,
166187
],
188+
[[makeUnionType('', ['0', '-1']), integer], true],
167189
[
168190
[
169191
makeObjectType('', {
@@ -537,6 +559,8 @@ typeAssignabilitySuite('custom types (not assignable)', [
537559
[makeUnionType('', ['a', 'b', 'c']), makeUnionType('', ['b', 'c', 'd'])],
538560
false,
539561
],
562+
[[makeUnionType('', ['-1']), naturalNumber], false],
563+
[[makeUnionType('', ['-0']), integer], false],
540564
[
541565
[
542566
makeObjectType('', {

src/language/semantics/type-system/prelude-types.ts

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,29 @@ export const nullType = makeUnionType('null', ['null'])
1616

1717
export const boolean = makeUnionType('boolean', ['false', 'true'])
1818

19+
// The current type hierarchy for opaque types is:
20+
// - string
21+
// - integer
22+
// - natural_number
23+
1924
export const string = makeOpaqueStringType('string', {
2025
isAssignableFromLiteralType: (_literalType: string) => true,
21-
nearestOpaqueAssignableFrom: () => optionADT.makeSome(naturalNumber),
26+
nearestOpaqueAssignableFrom: () => optionADT.makeSome(integer),
2227
nearestOpaqueAssignableTo: () => optionADT.none,
2328
})
2429

30+
export const integer = makeOpaqueStringType('natural_number', {
31+
isAssignableFromLiteralType: literalType =>
32+
/^(?:0|-?[1-9](?:[0-9])*)+$/.test(literalType),
33+
nearestOpaqueAssignableFrom: () => optionADT.makeSome(naturalNumber),
34+
nearestOpaqueAssignableTo: () => optionADT.makeSome(string),
35+
})
36+
2537
export const naturalNumber = makeOpaqueStringType('natural_number', {
2638
isAssignableFromLiteralType: literalType =>
27-
/(?:0|[1-9](?:[0-9])*)+/.test(literalType),
39+
/^(?:0|[1-9](?:[0-9])*)+$/.test(literalType),
2840
nearestOpaqueAssignableFrom: () => optionADT.none,
29-
nearestOpaqueAssignableTo: () => optionADT.makeSome(string),
41+
nearestOpaqueAssignableTo: () => optionADT.makeSome(integer),
3042
})
3143

3244
export const object = makeObjectType('object', {})

0 commit comments

Comments
 (0)