diff --git a/src/end-to-end.test.ts b/src/end-to-end.test.ts index 1f23d4c..1be77eb 100644 --- a/src/end-to-end.test.ts +++ b/src/end-to-end.test.ts @@ -339,7 +339,7 @@ testCases(endToEnd, code => code)('end-to-end tests', [ 4`, either.makeRight('10'), ], - [`{ f: _ => 1 + 1 }.f(whatever)`, either.makeRight('2')], + [`{ f: _ => 5 % 3 }.f(whatever)`, either.makeRight('2')], [ `{ one: 1 diff --git a/src/language/semantics/prelude.ts b/src/language/semantics/prelude.ts index d592d8a..5e8266f 100644 --- a/src/language/semantics/prelude.ts +++ b/src/language/semantics/prelude.ts @@ -21,4 +21,5 @@ export const prelude = makeObjectNode({ '-': integer.subtract, '<': integer.less_than, '>': integer.greater_than, + '%': natural_number.modulo, }) diff --git a/src/language/semantics/stdlib/natural-number.ts b/src/language/semantics/stdlib/natural-number.ts index 4e35f34..52a264b 100644 --- a/src/language/semantics/stdlib/natural-number.ts +++ b/src/language/semantics/stdlib/natural-number.ts @@ -75,4 +75,44 @@ export const natural_number = { : 'false', ), ), + modulo: preludeFunction( + ['natural_number', 'modulo'], + { + parameter: types.naturalNumber, + return: makeFunctionType('', { + parameter: types.naturalNumber, + return: types.naturalNumber, + }), + }, + number2 => + either.makeRight( + makeFunctionNode( + { + parameter: types.naturalNumber, + return: types.naturalNumber, + }, + serializeOnceAppliedFunction(['natural_number', 'modulo'], number2), + option.none, + number1 => { + if ( + typeof number1 !== 'string' || + !types.naturalNumber.isAssignableFrom( + makeUnionType('', [number1]), + ) || + typeof number2 !== 'string' || + !types.naturalNumber.isAssignableFrom( + makeUnionType('', [number2]), + ) + ) { + return either.makeLeft({ + kind: 'panic', + message: 'numbers must be atoms', + }) + } else { + return either.makeRight(String(BigInt(number1) % BigInt(number2))) + } + }, + ), + ), + ), }