diff --git a/src/__tests__/parser.spec.ts b/src/__tests__/parser.spec.ts index 791e42d..3b519c2 100644 --- a/src/__tests__/parser.spec.ts +++ b/src/__tests__/parser.spec.ts @@ -151,8 +151,21 @@ describe('Line parser', () => { expect(result.type).toBe('equal temperament'); }); - it('rejects N-of-EDO without a numerator', () => { - expect(() => parseLine('\\8')).toThrow(); + it('accepts N-of-EDO without a numerator', () => { + const result = parseLine('\\8'); + expect( + result.equals( + new Interval( + ExtendedMonzo.fromEqualTemperament( + 0, + 2, + DEFAULT_NUMBER_OF_COMPONENTS + ), + 'equal temperament' + ) + ) + ).toBeTruthy(); + expect(result.type).toBe('equal temperament'); }); it('parses monzos', () => { diff --git a/src/parser.ts b/src/parser.ts index bbfb61b..e79eb67 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -45,7 +45,7 @@ type FractionLiteral = { type EdjiFraction = { type: 'EdjiFraction'; - numerator: number; + numerator?: number; denominator: number; equave: null | PlainLiteral | FractionLiteral; }; @@ -199,7 +199,7 @@ function evaluateAst( ); } if (ast.type === 'EdjiFraction') { - const fractionOfEquave = new Fraction(ast.numerator, ast.denominator); + const fractionOfEquave = new Fraction(ast.numerator ?? 0, ast.denominator); let equave: Fraction | undefined; if (ast.equave?.type === 'PlainLiteral') { equave = new Fraction(ast.equave.value); diff --git a/src/sw2.pegjs b/src/sw2.pegjs index e13af9a..a382049 100644 --- a/src/sw2.pegjs +++ b/src/sw2.pegjs @@ -132,7 +132,7 @@ EquaveExpression = '<' _ @(SlashFraction / PlainNumber) _ '>' BackslashFraction - = numerator:Integer '\\' denominator:SignedInteger equave:EquaveExpression? { return EdjiFraction(numerator, denominator, equave) } + = numerator:Integer? '\\' denominator:SignedInteger equave:EquaveExpression? { return EdjiFraction(numerator, denominator, equave) } Component = $([+-]? (SlashFraction / PlainNumber))