Module:Script-MBTL: Difference between revisions

From Mizuumi Wiki
Jump to navigation Jump to search
No edit summary
(trying to contain error 24)
Line 202: Line 202:
self.readb = self.backup_readb
self.readb = self.backup_readb
self.peek = " "
self.peek = " "
if not color[word] then error("unrecognized word") end
if not color[word:sub(1,1)] then error("unrecognized word") end
return self:wswitch(word:sub(1,1))
return self:wswitch(word:sub(1,1))
end
end

Revision as of 02:26, 15 December 2023

Documentation for this module may be created at Module:Script-MBTL/doc

local p = {}

--custom script for the IS wiki, feel free to make a copy of it or take any part of the code for other wikis. ohoho I DID!!!!! 
--MBTL wiki fork

--split multiple properties passed as a single param to a template call and return the converted property text


--local objects used by p.gameInput()
local Type = {WORD=0, CONNECTOR=1, PREFIX=2, SUFFIX=3, SYMBOL=4, BUTTON=5, DIRECTION=6, SYS=7}

local Token = {
	ttype = nil,
	targ = nil,
	new = function(self,typ,arg)
		t = {}
		self.ttype = typ
		self.targ = arg
		setmetatable(t,self)
		self.__index = self
		return t
	end
}

local color = {
	["A"] = "#e2258a",
	["B"] = "#ff7606",
	["C"] = "#36b270",
	["D"] = "#1e8bcb",
	["X"] = "#686868",
}

local lexer = {
	buffer = "",
	readb = "",
	peek = " ",
	backup_buffer = "",
	backup_readb = "",
	newBuffer = function(self,buf)
		self.buffer = buf
	end,
	readch = function(self)
		if self.buffer:len() >= 1 then
			local r = self.buffer:sub(1,1)
			self.readb = self.readb .. r
			self.buffer = self.buffer:sub(2,-1)
			self.peek = r
		else
			self.peek = ":EOF:"
		end
	end,
	scan = function(self)
		while self.peek==" " or self.peek=="\t" or self.peek=="\n" or self.peek=="\r" do
			self:readch()
		end
		return self:cswitch()
	end,
	cswitch = function(self)
		if self.peek == ">" then 
			self.peek = " "
			return Token:new(Type.CONNECTOR," > ")
		elseif self.peek == "," then
			self.peek = " "
			return Token:new(Type.CONNECTOR," , ")
		elseif self.peek == "(" then
			self.peek = " "
			return Token:new(Type.SYMBOL,"(")
		elseif self.peek == ")" then
			self.peek = " "
			return Token:new(Type.SYMBOL,")")
		elseif self.peek == "[" then
			self.peek = " "
			return Token:new(Type.SYMBOL,"[")
		elseif self.peek == "]" then
			self.peek = " "
			return Token:new(Type.SYMBOL,"]")
		elseif self.peek == "{" then
			self.peek = " "
			return Token:new(Type.SYMBOL,"{")
		elseif self.peek == "}" then
			self.peek = " "
			return Token:new(Type.SYMBOL,"}")
		elseif self.peek == "~" then
			self.peek = " "
			return Token:new(Type.CONNECTOR,"~")
		elseif self.peek == "+" then
			self.peek = " "
			return Token:new(Type.CONNECTOR,"+")
		elseif self.peek == "/" then
			self.peek = " "
			return Token:new(Type.CONNECTOR,"/")
		elseif self.peek == ":EOF:" then
			self.peek = " "
			return Token:new(Type.SYS,"EOF")
		else
			if tonumber(self.peek) == nil then
				local w = ""
				self.backup_buffer = self.buffer
				self.backup_readb = self.readb
				repeat
					w = w .. self.peek
					self:readch()
				until self.peek:match("%a")==nil or self.peek:match(":EOF:") --peek is not a letter or reached EOF
				if self.peek=="." then self.peek=" " end
				return self:wswitch(w)
			else
				local d = ""
				repeat
					d = d .. self.peek
					self:readch()
				until tonumber(self.peek) == nil
				return Token:new(Type.DIRECTION,d)
			end
		end
	end,
	wswitch = function(self,word)
		if word=="dl" then
			return Token:new(Type.PREFIX,"dl.")
		elseif word=="j" or word=="J" then
			return Token:new(Type.PREFIX,"j.")
		elseif word=="dj" or word=="DJ" then
			return Token:new(Type.PREFIX,"dj.")
		elseif word=="w" or word=="W" then
			return Token:new(Type.PREFIX,"w.")
		elseif word=="tk" or word=="TK" then
			return Token:new(Type.PREFIX,"tk.")
		elseif word=="md" then
			return Token:new(Type.PREFIX,"md.")
		elseif word=="A" then
			return Token:new(Type.BUTTON,"A")
		elseif word=="B" then
			return Token:new(Type.BUTTON,"B")
		elseif word=="C" then
			return Token:new(Type.BUTTON,"C")
		elseif word=="D" then
			return Token:new(Type.BUTTON,"D")
		elseif word=="X" then
			return Token:new(Type.BUTTON,"X")
		elseif word=="jc" then
			return Token:new(Type.WORD,"jc")
		elseif word=="sj" or word=="superjump" then
			return Token:new(Type.WORD,"sj")
		elseif word=="sjc" or word=="SJC" then
			return Token:new(Type.WORD,"sjc")
		elseif word=="djc" then
			return Token:new(Type.WORD,"djc")
		elseif word=="IAD" or word=="iad" then
			return Token:new(Type.WORD,"IAD")
		elseif word=="AT" or word=="at" then
			return Token:new(Type.WORD,"AT")
		elseif word=="OR" or word=="or" then
			return Token:new(Type.WORD," OR ")
		elseif word=="CH" or word=="ch" then
			return Token:new(Type.WORD,"CH ")
		elseif word=="FC" or word=="fc" then
			return Token:new(Type.WORD,"FC ")
		elseif word=="OTG" or word=="otg" then
			return Token:new(Type.WORD,"OTG ")
		elseif word=="MD" then
			return Token:new(Type.WORD,"MD")
		elseif word=="AD" or word=="ad" then
			return Token:new(Type.WORD,"AD")
		elseif word=="LA" or word=="la" then
			return Token:new(Type.WORD,"LA")
		elseif word=="RB" or word=="rb" then
			if self.peek=="1" then
				self.peek = " "
				return Token:new(Type.WORD,"RB1")
			elseif self.peek=="2" then
				self.peek = " "
				return Token:new(Type.WORD,"RB2")
			else return nil
			end
		elseif word=="Delay" or word=="delay" then
			return Token:new(Type.WORD,"delay")
		elseif word=="Heat" or word=="heat" then
			return Token:new(Type.WORD,"Heat")
		elseif word=="Dash" or word=="dash" then
			return Token:new(Type.WORD,"Dash")
		elseif word=="Airdash" or word=="airdash" then
			return Token:new(Type.WORD,"Airdash")
		elseif word=="Microdash" or word=="microdash" then
			return Token:new(Type.WORD,"Microdash")
		elseif word=="Throw" or word=="throw" then
			return Token:new(Type.WORD,"Throw")
		elseif word=="Sideswap" or word=="sideswap" then
			return Token:new(Type.WORD,"Sideswap")
		elseif word=="Jump" or word=="jump" then
			return Token:new(Type.WORD,"Jump")
		elseif word=="Doublejump" or word=="doublejump" then
			return Token:new(Type.WORD,"Doublejump")
		elseif word=="Land" or word=="land" then
			return Token:new(Type.WORD,"land")
		elseif word=="Rebeat" or word=="rebeat" then
			return Token:new(Type.WORD,"Rebeat")
		elseif word=="Starter" or word=="starter" then
			return Token:new(Type.WORD,"Starter")
		elseif word=="Ender" or word=="ender" then
			return Token:new(Type.WORD,"Ender")
		else
			self.buffer = self.backup_buffer
			self.readb = self.backup_readb
			self.peek = " "
			if not color[word:sub(1,1)] then error("unrecognized word") end
			return self:wswitch(word:sub(1,1))
		end
	end,
}

local parser = {
	v = {COMBOLIST=0, COMBOLISTP=1, COMBO=2, INPUTLIST=3, INPUTLISTP=4, INPUTN=5, INPUT=6, BLOCKLIST=7, BLOCKLISTP=8, BLOCK=9, UCPREFIXLIST=10, UCPREFIX=11, PREFIXLIST=12, PREFIX=13, DIR=14, BTNSLIST=15, BTNSLISTP=16, BTNS=17, SUFFIXLIST=18, SUFFIX=19, BTN=20, BTNP=21},
	look = Token:new(Type.SYS,"START"),
	
	move = function(self)
		self.look = lexer:scan()
	end,
	
	formatElem = function(self,t,clr)
		if clr then
			return "<span style=\"color:" .. clr .. ";\">" .. (t.targ or t) .. "</span>" --works because the or is lazy so if t is a token it will not return t even if it's technically not nil because t.targ comes first
		else
			return t.targ or t
		end
	end,
	
	start = function(self)
		self:move()
		return (self:combolist()) --only return the line parameter
	end,
	
	combolist = function(self)
		if self:first(self.v.COMBOLIST) then
			local c_line = self:combo()
			local cp_line = self:combolistp()
			if self.look.targ~="EOF" then error("illegal token: " .. self.look.targ) end
			return c_line..cp_line
		else error("illegal starting token") end
	end,
	
	combolistp = function(self)
		if self:first(self.v.COMBOLISTP) then
			local c_line = self:combo()
			local cp_line = self:combolistp()
			return c_line..cp_line
		elseif not self:follow(self.v.COMBOLISTP) then return error("illegal token: " .. self.look.targ)
		else return "" end
	end,
	
	combo = function(self)
		if self:first(self.v.COMBO) then
			local ret_line
			if self.look.targ=="(" then
				ret_line = self:formatElem(self.look)
				self:move()
				ret_line = ret_line .. self:inputlist()
				if self.look.targ==")" then
					ret_line = ret_line .. self:formatElem(self.look)
					self:move()
				else error("illegal token: " .. self.look.targ) end
			else ret_line = self:inputlist() end
			return ret_line
		else error("illegal token: " .. self.look.targ) end
	end,
	
	inputlist = function(self)
		if self:first(self.v.INPUTLIST) then
			local ret_line
			ret_line = self:input()
			ret_line = ret_line .. self:inputlistp()
			return ret_line
		else error("illegal token: " .. self.look.targ) end
	end,
	
	inputlistp = function(self)
		if self:first(self.v.INPUTLISTP) then
			local ret_line
			ret_line = self:formatElem(self.look)
			self:move()
			ret_line = ret_line .. self:inputn()
			ret_line = ret_line .. self:inputlistp()
			return ret_line
		elseif not self:follow(self.v.INPUTLISTP) then return error("illegal token: " .. self.look.targ)
		else return "" end
	end,
	
	inputn = function(self)
		if self:first(self.v.INPUTN) then
			return (self:input())
		elseif not self:follow(self.v.INPUTN) then return error("illegal token: " .. self.look.targ)
		else return "" end
	end,
	
	input = function(self)
		if self:first(self.v.INPUT) then
			local ret_line
			if self.look.ttype==Type.WORD then
				ret_line = self:formatElem(self.look)
				self:move()
			elseif self.look.ttype==Type.CONNECTOR then
			  ret_line = self:formatElem(self.look)
			  self:move()
			else ret_line = self:blocklist() end
			return ret_line
		else error("illegal token: " .. self.look.targ) end
	end,
	
	blocklist = function(self)
		if self:first(self.v.BLOCKLIST) then
			local ret_line
			ret_line = self:block()
			ret_line = ret_line .. self:blocklistp()
			return ret_line
		else error("illegal token: " .. self.look.targ) end
	end,
	
	blocklistp = function(self)
		if self:first(self.v.BLOCKLISTP) then
			local ret_line
			ret_line = self:formatElem(self.look)
			self:move()
			ret_line = ret_line .. self:block()
			ret_line = ret_line .. self:blocklistp()
			return ret_line
		elseif not self:follow(self.v.BLOCKLISTP) then return error("illegal token: " .. self.look.targ)
		else return "" end
	end,
	
	block = function(self)
		if self:first(self.v.BLOCK) then
			local ret_line
			local up = self:ucprefixlist()
			local pf = self:prefixlist()
			local bl_line, bl_button = self:btnslist()
			ret_line = self:formatElem(up) .. self:formatElem(pf,bl_button) .. bl_line
			return ret_line
		else error("illegal token: " .. self.look.targ) end
	end,
	
	ucprefixlist = function(self)
		if self:first(self.v.UCPREFIXLIST) then
			local ret_line
			ret_line = self:ucprefix()
			ret_line = ret_line .. self:ucprefixlist()
			return ret_line
		else return "" end
	end,
	
	ucprefix = function(self)
		if self:first(self.v.UCPREFIX) then
			local u = self.look.targ
			self:move()
			return u
		else return "" end
	end,
	
	prefixlist = function(self)
		if self:first(self.v.PREFIXLIST) then
			local ret_line
			ret_line = self:prefix()
			ret_line = ret_line .. self:prefixlist()
			return ret_line
		elseif not self:follow(self.v.PREFIXLIST) then return error("illegal token: " .. self.look.targ)
		else return "" end
	end,
	
	prefix = function(self)
		if self:first(self.v.PREFIX) then
			local p = self.look.targ
			self:move()
			return p
		else error("illegal token: " .. self.look.targ) end
	end,
	
	dir = function(self)
		if self:first(self.v.DIR) then
			local d = self.look.targ
			self:move()
			return d
		elseif not self:follow(self.v.DIR) then return error("illegal token: " .. self.look.targ)
		else return "" end
	end,
	
	btnslist = function(self)
		if self:first(self.v.BTNSLIST) then
			local ret_line, ret_button
			ret_line, ret_button = self:btns()
			ret_line = ret_line .. self:btnslistp()
			return ret_line, ret_button
		else error("illegal token: " .. self.look.targ) end
	end,
	
	btnslistp = function(self)
		if self:first(self.v.BTNSLISTP) then
			local ret_line
			if self.look.targ=="~" then
				ret_line = self:formatElem(self.look)
				self:move()
				ret_line = ret_line .. self:btns()
				ret_line = ret_line .. self:btnslistp()
				return ret_line
			elseif self:first(self.v.BTNS) then
				ret_line = self:btns()
				ret_line = ret_line .. self:btnslistp()
				return ret_line
			end
		elseif not self:follow(self.v.BTNSLISTP) then return error("illegal token: " .. self.look.targ)
		else return "" end
	end,
	
	btns = function(self)
		if self:first(self.v.BTNS) then
			local dr = self:dir()
			local b_line, b_button = self:btn()
			b_line = self:formatElem(dr,b_button) .. b_line .. self:suffixlist(b_button)
			return b_line, b_button
		else error("illegal token: " .. self.look.targ) end
	end,
	
	suffixlist = function(self,mainb)
		if self:first(self.v.SUFFIXLIST) then
			local ret_line
			ret_line = self:suffix(mainb)
			ret_line = ret_line .. self:suffixlist(mainb)
			return ret_line
		elseif not self:follow(self.v.SUFFIXLIST) then return error("illegal token: " .. self.look.targ)
		else return "" end
	end,
	
	suffix = function(self,mainb)
		if self:first(self.v.SUFFIX) then
			local ret_line
			ret_line = self:formatElem(self.look, mainb)
			self:move()
			local sufbody = ""
			if self.look.targ=="w." then
				sufbody = self:formatElem("w",mainb)
				self:move()
			else 
				sufbody = self:formatElem(self:dir(),mainb)
			end
			ret_line = ret_line .. sufbody
			if self.look.targ==")" then
				ret_line = ret_line .. self:formatElem(self.look,mainb)
				self:move()
				return ret_line
			else error("illegal token: " .. self.look.targ) end
		else error("illegal token: " .. self.look.targ) end
	end,
	
	btn = function(self)
		if self:first(self.v.BTN) then
			local ret_line, ret_button
			if self.look.ttype==Type.BUTTON then
				ret_button = color[self.look.targ]
				ret_line = self:formatElem(self.look,ret_button)
				self:move()
				ret_line = ret_line .. self:btnp()
				return ret_line, ret_button
			elseif self.look.targ=="[" then
				local pre = self.look.targ
				self:move()
				if self.look.ttype==Type.BUTTON then
					ret_button = color[self.look.targ]
					ret_line = self:formatElem(pre,ret_button)
					ret_line = ret_line .. self:formatElem(self.look,ret_button)
					self:move()
					ret_line = ret_line .. self:btnp()
					if self.look.targ=="]" then
						ret_line = ret_line .. self:formatElem(self.look,ret_button)
						self:move()
						return ret_line, ret_button
					else error("illegal token: " .. self.look.targ) end
				else error("illegal token: " .. self.look.targ) end
			elseif self.look.targ=="]" then
				local pre = self.look.targ
				self:move()
				if self.look.ttype==Type.BUTTON then
					ret_button = color[self.look.targ]
					ret_line = self:formatElem(pre,ret_button)
					ret_line = ret_line .. self:formatElem(self.look,ret_button)
					self:move()
					ret_line = ret_line .. self:btnp()
					if self.look.targ=="[" then
						ret_line = ret_line .. self:formatElem(self.look,ret_button)
						self:move()
						return ret_line, ret_button
					else error("illegal token: " .. self.look.targ) end
				else error("illegal token: " .. self.look.targ) end
			elseif self.look.targ=="{" then
				local pre = self.look.targ
				self:move()
				if self.look.ttype==Type.BUTTON then
					ret_button = color[self.look.targ]
					ret_line = self:formatElem(pre,ret_button)
					ret_line = ret_line .. self:formatElem(self.look,ret_button)
					self:move()
					ret_line = ret_line .. self:btnp()
					if self.look.targ=="}" then
						ret_line = ret_line .. self:formatElem(self.look,ret_button)
						self:move()
						return ret_line, ret_button
					else error("illegal token: " .. self.look.targ) end
				else error("illegal token: " .. self.look.targ) end
			elseif self.look.targ=="AT" then
				ret_line = self:formatElem(self.look)
				self:move()
				return ret_line
			end
		else error("illegal token: " .. self.look.targ) end
	end,
	
	btnp = function(self)
		if self:first(self.v.BTNP) then
			local ret_line
			ret_line = self:formatElem(self.look)
			self:move()
			if self.look.ttype==Type.BUTTON then
				local subb = color[self.look.targ]
				ret_line = ret_line .. self:formatElem(self.look,subb)
				self:move()
				ret_line = ret_line .. self:btnp()
				return ret_line
			else error("illegal token: " .. self.look.targ) end
		elseif not self:follow(self.v.BTNP) then return error("illegal token: " .. self.look.targ)
		else return "" end
	end,
	
	first = function(self,var)
		if var==self.v.COMBOLIST then return self:first(self.v.COMBO)
		elseif var==self.v.COMBOLISTP then return self:first(self.v.COMBO)
		elseif var==self.v.COMBO then return self.look.targ=="(" or self:first(self.v.INPUTLIST)
		elseif var==self.v.INPUTLIST then return self:first(self.v.INPUT)
		elseif var==self.v.INPUTLISTP then return self.look.ttype==Type.CONNECTOR
		elseif var==self.v.INPUTN then return self:first(self.v.INPUT)
		elseif var==self.v.INPUT then return self.look.ttype==Type.WORD or self.look.ttype==Type.CONNECTOR or self:first(self.v.BLOCKLIST)
		elseif var==self.v.BLOCKLIST then return self:first(self.v.BLOCK)
		elseif var==self.v.BLOCKLISTP then return self.look.targ=="/"
		elseif var==self.v.BLOCK then return self.look.ttype==Type.DIRECTION or self:first(self.v.PREFIXLIST) or self:first(self.v.BTNSLIST)
		elseif var==self.v.UCPREFIXLIST then return self:first(self.v.UCPREFIX)
		elseif var==self.v.COMBOLISTP then return self:first(self.v.COMBO)
		elseif var==self.v.UCPREFIX then return self.look.targ=="dl." or self.look.targ=="tk." or self.look.targ=="w."
		elseif var==self.v.PREFIXLIST then return self:first(self.v.PREFIX)
		elseif var==self.v.PREFIX then return self.look.ttype==Type.PREFIX
		elseif var==self.v.DIR then return self.look.ttype==Type.DIRECTION
		elseif var==self.v.BTNSLIST then return self:first(self.v.BTNS)
		elseif var==self.v.BTNSLISTP then return self.look.targ=="~" or self:first(self.v.BTNS)
		elseif var==self.v.BTNS then return self.look.ttype==Type.DIRECTION or self:first(self.v.BTN)
		elseif var==self.v.SUFFIXLIST then return self:first(self.v.SUFFIX)
		elseif var==self.v.SUFFIX then return self.look.targ=="("
		elseif var==self.v.BTN then return self.look.ttype==Type.BUTTON or self.look.targ=="AT" or self.look.targ=="[" or self.look.targ=="]" or self.look.targ=="{"
		elseif var==self.v.BTNP then return self.look.targ=="+"
		else return false end
	end,
	
	follow = function(self, var)
		if var==self.v.COMBOLISTP then return self.look.targ=="(" or self.look.targ==")" or self.look.ttype==Type.CONNECTOR or self.look.targ=="EOF"
		elseif var==self.v.INPUTLISTP then return self.look.ttype==Type.WORD or self.look.ttype==Type.PREFIX or self.look.ttype==Type.BUTTON or self.look.ttype==Type.DIRECTION or self.look.targ==")" or self.look.targ=="(" or self.look.targ=="]" or self.look.targ=="[" or self.look.targ=="{" or self.look.targ=="EOF"
		elseif var==self.v.INPUTN then return self.look.ttype==Type.CONNECTOR or self.look.ttype==Type.WORD or self.look.ttype==Type.PREFIX or self.look.ttype==Type.BUTTON or self.look.ttype==Type.DIRECTION or self.look.targ==")" or self.look.targ=="(" or self.look.targ=="]" or self.look.targ=="[" or self.look.targ=="{" or self.look.targ=="EOF"
		elseif var==self.v.BLOCKLISTP then return self.look.ttype==Type.CONNECTOR or self.look.ttype==Type.WORD or self.look.ttype==Type.PREFIX or self.look.ttype==Type.BUTTON or self.look.ttype==Type.DIRECTION or self.look.targ==")" or self.look.targ=="(" or self.look.targ=="]" or self.look.targ=="[" or self.look.targ=="{" or self.look.targ=="EOF"
		elseif var==self.v.PREFIXLIST then return self.look.ttype==Type.BUTTON or self.look.ttype==Type.DIRECTION or self.look.targ=="]" or self.look.targ=="[" or self.look.targ=="]" or self.look.targ=="{"
		elseif var==self.v.DIR then return self.look.ttype==Type.BUTTON or self.look.targ=="]" or self.look.targ=="[" or self.look.targ=="]" or self.look.targ=="{"
		elseif var==self.v.BTNSLISTP then return self.look.ttype==Type.CONNECTOR or self.look.ttype==Type.WORD or self.look.ttype==Type.PREFIX or self.look.ttype==Type.BUTTON or self.look.ttype==Type.DIRECTION or self.look.targ=="/" or self.look.targ==")" or self.look.targ=="(" or self.look.targ=="]" or self.look.targ=="[" or self.look.targ=="{" or self.look.targ=="EOF"
		elseif var==self.v.SUFFIXLIST then return self.look.ttype==Type.CONNECTOR or self.look.ttype==Type.WORD or self.look.ttype==Type.PREFIX or self.look.ttype==Type.BUTTON or self.look.ttype==Type.DIRECTION or self.look.targ=="/" or self.look.targ=="~" or self.look.targ==")" or self.look.targ=="(" or self.look.targ=="]" or self.look.targ=="[" or self.look.targ=="{" or self.look.targ=="EOF"
		elseif var==self.v.BTNP then return self.look.ttype==Type.CONNECTOR or self.look.ttype==Type.WORD or self.look.ttype==Type.PREFIX or self.look.ttype==Type.BUTTON or self.look.ttype==Type.DIRECTION or self.look.targ=="/" or self.look.targ=="~" or self.look.targ==")" or self.look.targ=="(" or self.look.targ=="]" or self.look.targ=="[" or self.look.targ=="{" or self.look.targ=="}" or self.look.targ=="EOF"
		else return false end
	end,
}


--actual method functions
	
function p.multiprop(frame)
	
	local str = frame.args[1]
	local sep = ","
	local t={}
	--split properties
	for str in string.gmatch(str, "([^"..sep.."]+)") do
			table.insert(t, str)
	end
	--get the string done
	for index, prop in ipairs(t) do
		if prop:sub(1,1) == "%s" then
			prop = prop:sub(2,-1)
		end
		expanded = frame:expandTemplate{ title="Property-MBTL", args={prop,"IGNOREPROPERTYERROR"}}
		t[index] = expanded
	end
	
	ret = table.concat(t,", ")
	
	return ret
end

--color code and format game inputs.
--supports entire combos as arguments.
function p.gameInput(frame)
	
	local str = frame.args[1]
	lexer:newBuffer(str) --set the input string as the input buffer
	return parser:start()
	
end

return p