module lexer
interface LexerState
source: string
current: number
tokens: Token[]
interface Token
type: string
value: string
init source (LexerState, string -> LexerState) :=
{ self | source = source, current = 1, tokens = {} }
match pattern tokentype (LexerState, string, string -> LexerState, boolean) :=
let
position, value = self.source:match ('()(' .. pattern .. ')') self.current
in
if position == self.current then
let
token = { type = 'tokentype', value = value }
in
{ self |
current = self.current + 1,
tokens = self.tokens :: token,
}, true
else
self, false
lex done (LexerState, boolean? -> Token[]?, string?) :=
if not done then
let
self, success = self:match '[%a_][%w_]' 'name'
or self:match '%d*%.?%d+' 'number'
or self:match '%=' 'equals'
or self:match '%+' 'plus'
or self:match '%s+'
in
if success then
self:lex self.current <= #self.tokens
else
let
errformat = "unexpected character '%s'"
errmsg = errformat:format (self.source:sub self.current self.current)
in
nil, errmsg
else
self.tokens, nil
new ... (...any -> LexerState) =
let
self = setmetatable {} { __index = lexer }
in
init self ...
Last active
June 1, 2016 02:48
-
-
Save itsMapleLeaf/f4ff3d265bb615ef430ba906b4f3c64d to your computer and use it in GitHub Desktop.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment