diff --git a/src/parser/parser.ts b/src/parser/parser.ts index ce97be6..97c9668 100644 --- a/src/parser/parser.ts +++ b/src/parser/parser.ts @@ -62,7 +62,7 @@ const parseIntervalComments = (tokens: Token[], intervalDuration: Duration): [Co while (tokens[0]) { const [start, offset, text, ...rest] = tokens; if (start.type === "comment-start") { - if (!offset || offset.type !== "duration") { + if (!offset || offset.type !== "offset") { throw new ParseError( `Expected [comment offset] instead got ${tokenToString(offset)}`, offset?.loc || start.loc, @@ -73,7 +73,7 @@ const parseIntervalComments = (tokens: Token[], intervalDuration: Duration): [Co } comments.push({ // when offset is negative, recalculate it based on interval length - offset: new Duration(offset.value >= 0 ? offset.value : intervalDuration.seconds + offset.value), + offset: new Duration(offset.kind === "absolute" ? offset.value : intervalDuration.seconds - offset.value), text: text.value, loc: offset.loc, }); diff --git a/src/parser/tokenizer.ts b/src/parser/tokenizer.ts index 4b273a1..bc87bd0 100644 --- a/src/parser/tokenizer.ts +++ b/src/parser/tokenizer.ts @@ -36,6 +36,12 @@ export type NumberToken = { value: number; loc: SourceLocation; }; +export type OffsetToken = { + type: "offset"; + kind: "absolute" | "relative-plus" | "relative-minus"; + value: number; + loc: SourceLocation; +}; export type RangeIntensityToken = { type: "intensity-range"; value: [number, number]; @@ -46,7 +52,14 @@ export type CommentStartToken = { value?: undefined; loc: SourceLocation; }; -export type Token = HeaderToken | IntervalToken | TextToken | NumberToken | RangeIntensityToken | CommentStartToken; +export type Token = + | HeaderToken + | IntervalToken + | TextToken + | NumberToken + | OffsetToken + | RangeIntensityToken + | CommentStartToken; const toInteger = (str: string): number => { return parseInt(str.replace(/[^0-9]/, ""), 10); @@ -93,13 +106,17 @@ const tokenizeComment = (line: string, row: number): Token[] | undefined => { if (!commentHead) { return undefined; } - const sign = minus ? -1 : 1; if (!DURATION_REGEX.test(offset)) { throw new ParseError("Invalid comment offset", { row, col: commentHead.length }); } return [ { type: "comment-start", loc: { row, col: line.indexOf("@") } }, - { type: "duration", value: sign * toSeconds(offset), loc: { row, col: commentHead.length } }, + { + type: "offset", + kind: minus ? "relative-minus" : "absolute", + value: toSeconds(offset), + loc: { row, col: commentHead.length }, + }, { type: "text", value: commentText.trim(), loc: { row, col: commentHead.length + offset.length } }, ]; };