japl/nimjapl/lexer.nim

86 lines
2.6 KiB
Nim
Raw Normal View History

2020-08-05 16:16:12 +02:00
import tables
import meta/tokentype
import meta/tokenobject
import meta/exceptions
import strformat
import system
const TOKENS = to_table({
"(": TokenType.LP, ")": TokenType.RP,
"{": TokenType.LB, "}": TokenType.RB,
".": TokenType.DOT, ",": TokenType.COMMA,
"-": TokenType.MINUS, "+": TokenType.PLUS,
";": TokenType.SEMICOLON, "*": TokenType.STAR,
">": TokenType.GT, "<": TokenType.LT,
"=": TokenType.EQ, "!": TokenType.NEG,
"/": TokenType.SLASH, "%": TokenType.MOD})
const RESERVED = to_table({
"or": TokenType.OR, "and": TokenType.AND,
"class": TokenType.CLASS, "fun": TokenType.FUN,
"if": TokenType.IF, "else": TokenType.ELSE,
"for": TokenType.FOR, "while": TokenType.WHILE,
"var": TokenType.VAR, "nil": TokenType.NIL,
"true": TokenType.TRUE, "false": TokenType.FALSE,
"return": TokenType.RETURN,
"this": TokenType.THIS, "super": TokenType.SUPER,
"del": TokenType.DEL, "break": TokenType.BREAK})
type Lexer* = object
source: string
tokens: seq[Token]
line: int
start: int
current: int
func initLexer*(source: string): Lexer =
result = Lexer(source: source, tokens: @[], line: 1, start: 0, current: 0)
proc step*(self: var Lexer): char =
result = self.source[self.current]
self.current = self.current + 1
proc done*(self: Lexer): bool =
result = self.current >= self.source.len
proc peek*(self: Lexer): string =
if self.done():
result = ""
else:
result = &"{self.source[self.current]}"
proc peekNext*(self: Lexer): string =
if self.current + 1 >= self.source.len:
result = ""
else:
result = &"{self.source[self.current + 1]}"
proc createToken*[T](self: var Lexer, tokenType: TokenType, literal: T): Token =
result = Token(kind: tokenType,
lexeme: self.source[self.start..self.current],
literal: literal
)
proc parseString*(self: var Lexer, delimiter: string) =
while self.peek() != delimiter and not self.done():
if self.peek() == "\n":
self.line = self.line + 1
discard self.step()
if self.done():
raise newException(ParseError, &"Unterminated string literal at {self.line}")
discard self.step()
let value = self.source[self.start + 1..self.current - 1] # Get the value between quotes
let token = self.createToken[string](STR, value)
var lexer = initLexer("print")
echo lexer.createToken[string](STR, "ehlo", STR)