import std/[strutils, strformat] from ../token import Token, TokenKind from ast import ASTNodeKind, ASTNode, printNode import ../error_reporting type Parser* = object pos: int tokens: seq[Token] tree: ASTNode func initParser*(tokens: seq[Token]): Parser = Parser(pos: 0, tokens: tokens) # Helpers func atEnd*(parser: Parser): bool = parser.pos >= parser.tokens.len func advance*(parser: var Parser): Token = if not parser.atEnd: result = parser.tokens[parser.pos] parser.pos += 1 func peek*(parser: Parser): Token = if not parser.atEnd: result = parser.tokens[parser.pos] func prev*(parser: Parser): Token = parser.tokens[parser.pos - 1] func match*(parser: var Parser, tk: TokenKind): bool = if not parser.atEnd and parser.peek.kind == tk: discard parser.advance() result = true func consume*(parser: var Parser, tk: TokenKind, msg: string): Token = ## Attempt to consume a token of the given kind, and raise an error if ## we cannot for whatever reason if not parser.atEnd and parser.peek.kind == tk: result = parser.advance() raise parserError(parser.pos, parser.peek.kind, msg) # Expression parser # {.push warning[UnusedImport]: off.} import expression