Skip to content

Commit 690d344

Browse files
committed
Add boolean.and & boolean.or to prelude
Also `&&` & `||` aliases.
1 parent 116e53c commit 690d344

File tree

2 files changed

+80
-1
lines changed

2 files changed

+80
-1
lines changed

src/language/semantics/prelude.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,6 @@ export const prelude = makeObjectNode({
2222
'<': integer.less_than,
2323
'>': integer.greater_than,
2424
'%': natural_number.modulo,
25+
'&&': boolean.and,
26+
'||': boolean.or,
2527
})

src/language/semantics/stdlib/boolean.ts

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
import either from '@matt.kantor/either'
2+
import option from '@matt.kantor/option'
3+
import { makeFunctionNode } from '../function-node.js'
24
import { type SemanticGraph } from '../semantic-graph.js'
35
import { types } from '../type-system.js'
4-
import { preludeFunction } from './stdlib-utilities.js'
6+
import {
7+
preludeFunction,
8+
serializeOnceAppliedFunction,
9+
} from './stdlib-utilities.js'
510

611
type BooleanNode = 'true' | 'false'
712
const nodeIsBoolean = (node: SemanticGraph): node is BooleanNode =>
@@ -33,4 +38,76 @@ export const boolean = {
3338
}
3439
},
3540
),
41+
and: preludeFunction(
42+
['boolean', 'and'],
43+
{
44+
parameter: types.boolean,
45+
return: types.boolean,
46+
},
47+
argument2 => {
48+
if (!nodeIsBoolean(argument2)) {
49+
return either.makeLeft({
50+
kind: 'panic',
51+
message: 'argument was not a boolean',
52+
})
53+
} else {
54+
return either.makeRight(
55+
makeFunctionNode(
56+
{
57+
parameter: types.boolean,
58+
return: types.integer,
59+
},
60+
serializeOnceAppliedFunction(['boolean', 'and'], argument2),
61+
option.none,
62+
argument1 => {
63+
if (!nodeIsBoolean(argument1)) {
64+
return either.makeLeft({
65+
kind: 'panic',
66+
message: 'argument was not a boolean',
67+
})
68+
} else {
69+
return either.makeRight(String(argument1 && argument2))
70+
}
71+
},
72+
),
73+
)
74+
}
75+
},
76+
),
77+
or: preludeFunction(
78+
['boolean', 'or'],
79+
{
80+
parameter: types.boolean,
81+
return: types.boolean,
82+
},
83+
argument2 => {
84+
if (!nodeIsBoolean(argument2)) {
85+
return either.makeLeft({
86+
kind: 'panic',
87+
message: 'argument was not a boolean',
88+
})
89+
} else {
90+
return either.makeRight(
91+
makeFunctionNode(
92+
{
93+
parameter: types.boolean,
94+
return: types.integer,
95+
},
96+
serializeOnceAppliedFunction(['boolean', 'or'], argument2),
97+
option.none,
98+
argument1 => {
99+
if (!nodeIsBoolean(argument1)) {
100+
return either.makeLeft({
101+
kind: 'panic',
102+
message: 'argument was not a boolean',
103+
})
104+
} else {
105+
return either.makeRight(String(argument1 || argument2))
106+
}
107+
},
108+
),
109+
)
110+
}
111+
},
112+
),
36113
}

0 commit comments

Comments
 (0)