Skip to content

Instantly share code, notes, and snippets.

@x4fx77x4f
Created March 27, 2021 23:28
Show Gist options
  • Save x4fx77x4f/55ce1af230e306f2c5868a908236f3ec to your computer and use it in GitHub Desktop.
Save x4fx77x4f/55ce1af230e306f2c5868a908236f3ec to your computer and use it in GitHub Desktop.
Very basic BASIC lexer in Lua
--@name BASIC
--@server
local code = [[
10 PRINT "Hello, World!"
20 END
]]
local lexer = {}
lexer.data = code
lexer.index = 1
lexer.len = #code
lexer.out = {}
function lexer:eof()
return self.index > self.len
end
function lexer:nextChars(n)
local index = self.index
return string.sub(self.data, index, index+(n and n-1 or 0))
end
function lexer:consumeChars(n)
n = n or 1
local chars = self:nextChars(n)
self.index = self.index+n
return chars
end
function lexer:consumeWhile(cond)
local out = {}
local i = 1
while true do
local char = self:nextChars(1)
if cond(char) then
self.index = self.index+1
out[i] = char
i = i+1
else
break
end
end
return table.concat(out)
end
function lexer.isNumber(str)
return string.find(str, '%d')
end
function lexer.isWhitespace(str)
return string.find(str, '%s')
end
function lexer.isAlphabetic(str)
return string.find(str, '%a')
end
function lexer.isNotQuote(str)
return str ~= '"'
end
function lexer:consumeString()
assert(not self.isNotQuote(self:consumeChars()), "missing beginning quote")
local str = self:consumeWhile(self.isNotQuote)
self.index = self.index+1
return str
end
function lexer:consumeLine()
if self:nextChars() == '\n' then
self.index = self.index+1
return
end
local lineno = self:consumeWhile(self.isNumber)
self:consumeWhile(self.isWhitespace)
local keyword = self:consumeWhile(self.isAlphabetic)
self:consumeWhile(self.isWhitespace)
local arguments = {}
if keyword == 'PRINT' then
arguments[1] = self:consumeString()
end
self.out[lineno] = {
keyword = keyword,
arguments = arguments
}
assert(self:consumeChars() == '\n' or self:eof(), "too many parameters")
end
function lexer:consumeLines()
while not self:eof() do
self:consumeLine()
end
end
lexer:consumeLines()
do return printTable(lexer.out) end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment