mherkender / lua.js

An ECMAscript framework to compile and run Lua code, allowing Lua to run in a browser or in Flash
http://blog.brokenfunction.com/
600 stars 73 forks source link

Bug in operator < #24

Open CarlosEFML opened 11 years ago

CarlosEFML commented 11 years ago

for some reason, the following code doesn't work (parser error) with lua+parser.min.js & lua+parser.js:

    local px = obj1:getPx()
    if (px<self.targetPos[1]) then

replacing

px<self.targetPos[1]

with

self.targetPos[1]>px

works great.

if the second operator is a numeric constant, everything works great also.

mherkender commented 11 years ago

I added a series of tests (tests/optest.lua) to try and figure out what's going on, but I wasn't able to reproduce this. Can you provide me with an isolated chunk of code that reproduces this error?

CarlosEFML commented 11 years ago

that's my source code (main.html, graphicsWEB.js and tcpSocketWEB.js). Locate

if(px<self.targetPos[1]) then

in main.html

Error message: [20:32:42.936] Error: Parse error on line 564: ...= obj1:getPx()if(px=self.targetPos[1]) ----------------------^ Expecting 'EOF', ';', '(', ')', 'LOCAL', 'DO', 'END', 'WHILE', 'REPEAT', 'UNTIL', 'IF', 'FOR', ',', 'FUNCTION', ':', 'NAME', 'RETURN', 'BREAK', 'ELSE', 'ELSEIF', 'THEN', '.', 'STRING', '+', '-', '*', '/', '^', '%', '..', '<', '>', '<=', '>=', '==', '~=', 'AND', 'OR', '{', '}', '[', ']', got '=' @ file:///C:/Users/Cadu/Downloads/LUA/WEB/MEUS_TESTES/teste2/lua+parser.js:613


main.html:

< html> < body oncontextmenu="return false;"> < canvas width='480' height='272' id='gameCanvas1' > < div id="divCode" style="display: none">

KEY_UP = 38 KEY_LEFT = 37 KEY_RIGHT = 39 KEY_DOWN = 40

GraphicsCallback = {}

function GraphicsCallback:new(callBack,data) result = {} setmetatable(result, self) self.__index = self

result.callBack = callBack result.data = data

return result end

KeysCallback = {}

function KeysCallback:new(callBack,data) result = {} setmetatable(result, self) self.__index = self

result.callBack = callBack result.data = data

return result end

PointerCallback = {}

function PointerCallback:new(callBack,data) result = {} setmetatable(result, self) self.__index = self

result.callBack = callBack result.data = data

return result end

GameObj = { sprite = nil, px = 0, py = 0, active = false, bbox = nil }

function GameObj:new() result = {} setmetatable(result, self) self.__index = self

return result end

function GameObj:Init() end

function GameObj:Draw() local frame = self.sprite:getFrame() if (frame==nil) then return end

if (self.sprite.animFlags[ANIM_FADE]==1) then local lFrame = self.sprite.sprites[self.sprite.lastFrame+1] local alpha1 = self.sprite.curFrameTime/self.sprite.frameTime

drawImageWithTransparency(lFrame,self.px,self.py,1-alpha1) drawImageWithTransparency(frame,self.px,self.py,alpha1) else drawImage(frame,self.px,self.py) end

end

function GameObj:Action(elapsedTime) end

function GameObj:Collide(other) local w1,h1,w2,h2,x1,y1,x2,y2

w1 = self.sprite:GetW() h1 = self.sprite:GetH() w2 = other.sprite:GetW() h2 = other.sprite:GetH()

x1 = self.px y1 = self.py x2 = other.px y2 = other.py

if ( ((x1 + w1) > x2) and ((y1 + h1) > y2) and ((x2 + w2) > x1) and ((y2 + h2) > y1) ) then return true else return false end end

function GameObj:getPx() return self.px end

function GameObj:getPy() return self.py end

function GameObj:setPx(px) self.px = px end

function GameObj:setPy(py) self.py = py end

function GameObj:getActive() return self.active end

function GameObj:setActive(active) self.active = active end

local MAX_SPRITE_FRAMES = 5 ANIM_LOOP = 1 ANIM_LOOPBACK = 2 ANIM_REWIND = 3 ANIM_END = 4 ANIM_FADE = 5

Sprite = { frame = 0, lastFrame = 0, nFrames = 0, frameTime = 0, curFrameTime = 0, animFlags = {0,0,0,0,0}, animationListener = nil, sprites = {} }

function Sprite:new(nFrames,frameTime) result = {} setmetatable(result, self) self.__index = self

result.nFrames = nFrames result.frameTime = frameTime

local i = 1 while (i<=nFrames) do result.sprites[i] = nil i=i+1 end

return result end

function Sprite:getFrame() return self.sprites[self.frame+1] end

function Sprite:GetW() return self.sprites[self.frame+1]:GetWidth() end

function Sprite:GetH() return self.sprites[self.frame+1]:GetHeight() end

function Sprite:setAnimFlags(flags) self.animFlags = flags end

function Sprite:getAnimFlags() return self.animFlags end

function Sprite:SelFrame(frameNo) self.lastFrame = self.frame

if( frameNo>=self.nFrames) then self.frame = self.nFrames-1 else self.frame = frameNo end

if (self.animationListener ~= nil) then self.animationListener.OnFrame(frameNo) end end

function Sprite:NextFrame() self.lastFrame = self.frame

if (self.nFrames<2) then return false end

if (self.animFlags[ANIM_REWIND]==1) then if (self.frame==0) then self.animFlags[ANIM_REWIND]=0 self.frame=1 else self.frame=self.frame-1 end

return true end

if (self.frame == (self.nFrames-1)) then if (self.animFlags[ANIM_LOOP]==1) then self.frame = 0 elseif (self.animFlags[ANIM_LOOPBACK]==1) then self.animFlags[ANIM_REWIND]=1 self.frame = self.frame-1 else self.animFlags[ANIM_END]=1 return false end else self.frame = self.frame+1 end

return true end

function Sprite:setAnimationListener(listener) self.animationListener = listener end

function Sprite:Animate(elapsedTime) if (self.animFlags[ANIM_FADE]==1) then if (self.lastFrame==self.frame) then self:NextFrame() end end

self.curFrameTime = self.curFrameTime + elapsedTime while (self.curFrameTime>=self.frameTime) do local animed = self:NextFrame() if ( (animed==true) and (self.animationListener~=nil) ) then self.animationListener.OnFrame(self.frame) end self.curFrameTime = self.curFrameTime - self.frameTime end end

function Sprite:getNFrames() return self.nFrames end

function Sprite:SetFrame(frameNo, image) self.sprites[frameNo] = image end

Shot = GameObj:new()

function Shot:new() result = {} setmetatable(result, self) self.__index = self

result.power = 0

return result end

function Shot:Init() end

function Shot:Action() end

function Shot:getPower() return self.power end

function Shot:setPower(power) self.power = power end

function Shot:getExplosionAnim() return nil end

SimpleDecoration = GameObj:new()

function SimpleDecoration:new(spr,px,py) result = {} setmetatable(result, self) self.__index = self

result.sprite = spr result.px = px result.py = py

return result end

function SimpleDecoration:Action(elapsedTime) self.sprite:Animate(elapsedTime) if (self.sprite:getAnimFlags()[ANIM_END]==1) then self:setActive(false) end end

AnimationData = { id = nil, numFrames = 0, animFlags = {}, animFPS = 0, frameName = nil, imgs = nil }

function AnimationData:new(id,numFrames,animFlags,animFPS,frameName) result = {} setmetatable(result, self) self.__index = self

result.id = id result.numFrames = numFrames result.animFlags = animFlags result.animFPS = animFPS result.frameName = frameName

return result end

local DEFAULT_ANIM_FPS = 30

INVALID_ANIM = 0 FOE1_WALK = 1 FOE1_ATTACK = 2 FOE1_DIE = 3 SHOT1 = 4 SHOT1Explode = 5

local animations = { AnimationData:new(FOE1_WALK,5,{ANIM_LOOPBACK},5,"FOE1Walk"), AnimationData:new(FOE1_ATTACK,5,{ANIM_LOOP},DEFAULT_ANIM_FPS,"FOE1Attack"), AnimationData:new(FOE1_DIE,5,{},DEFAULT_ANIMFPS,"FOE1Die"), AnimationData:new(SHOT1,1,{},1,"SHOT1"), AnimationData:new(SHOT1Explode,4,{ANIM_LOOPBACK},DEFAULT_ANIM_FPS,"SHOT1Explode"), AnimationData:new(INVALID_ANIM,0,{},0,0) }

Resource={}

function Resource:clearAnim(animIndex)

local animFrame = 1 while (animFrame<=animations[animIndex].numFrames) do print('devemos deletar animations[i].imgs[frame]') animations[animIndex].imgs[animFrame] = nil animFrame = animFrame+1 end

print('devemos deletar animations[i].imgs') animations[animIndex].imgs = nil end

function Resource:clear() local i=1 while (animations[i].id~=INVALID_ANIM) do self:clearAnim(i)

i=i+1 end end

function Resource:getAnim(animID) local i=1

while (animations[i].id~=INVALID_ANIM) do if (animations[i].id==animID) then if (animations[i].imgs == nil) then if (self:loadAnimImgs(i) == nil) then return nil end end return self:buildSprite(i) end i = i+1 end

return nil end

function Resource:buildSprite(animDataPos) local spr = Sprite:new(animations[animDataPos].numFrames,1/animations[animDataPos].animFPS) if (spr == nil) then return nil end

local i=1 while (i<=#animations[animDataPos].animFlags) do spr.animFlags[animations[animDataPos].animFlags[i]] = 1 i = i+1 end

i=1 while (i<=animations[animDataPos].numFrames) do spr:SetFrame(i,animations[animDataPos].imgs[i]) i = i+1 end

return spr end

function Resource:loadAnimImgs(animDataPos) local imgs = {}

local frame = 1 while (frame<=animations[animDataPos].numFrames) do imgs[frame] = loadImg(animations[animDataPos].frameName..(frame)..".png") if (imgs[frame]==nil) then self:clearAnim(animDataPos) return false end

frame = frame + 1 end

animations[animDataPos].imgs = imgs return true end

Shot1 = Shot:new()

function Shot1:new() result = {} setmetatable(result, self) self.__index = self

result.speed = 80 result.power = 1 result.sprite = nil

return result end

function Shot1:Init() self.sprite = Resource:getAnim(SHOT1) end

function Shot1:Action(elapsedTime) self.px = self.px + self.speed*(elapsedTime/1000) end

function Shot1:getExplosionAnim() local spr = Resource:getAnim(SHOT1Explode)

if (spr~=nil) then local explosion = SimpleDecoration:new(spr,self.px,self.py) if (explosion~=nil) then explosion:setActive(true) return explosion else print('devemos deletar spr') end end

return nil end

local s = tcpConnect("74.125.229.208",80) tcpSend(s,"GET\n")

local image = loadImg("flower.jpg")

local image2 = loadImg("Space_Background_bigger_transp.png")

local obj1 = GameObj:new()

obj1.sprite = Resource:getAnim(FOE1_WALK)

Game = { elapsedTotalGraphics = 0, elapsedTotalStatus = 0, gameFPS = 0, screenFPS = 0, keysStatus = {}, targetPos = {23,35} }

function Game:pointerUpdate(but,press,x,y) if(press==1) then self.targetPos[1]=x self.targetPos[2]=y end end

function Game:keysUpdate(code, press) self.keysStatus[code] = press end

numD = 1 function Game:updateGraphics() startFrame() clear()

drawImageWithTransparency(image,0,0,numD) numD = numD - 0.001

obj1:Draw()

drawLine(obj1:getPx(),0,obj1:getPx(),319, 255,0,0) drawLine(0,obj1:getPy(),800,obj1:getPy(), 255,0,0)

drawText("OIOI",0,0,100,16,255,255,255,50)

endFrame() end

function Game:updateStatus() if( self.keysStatus[KEY_DOWN] == 1) then obj1:setPy(obj1:getPy()+3) self.targetPos[1]=nil self.targetPos[2]=nil end if( self.keysStatus[KEY_UP] == 1) then obj1:setPy(obj1:getPy()-3) self.targetPos[1]=nil self.targetPos[2]=nil end if( self.keysStatus[KEY_LEFT] == 1) then obj1:setPx(obj1:getPx()-3) self.targetPos[1]=nil self.targetPos[2]=nil end if( self.keysStatus[KEY_RIGHT] == 1) then obj1:setPx(obj1:getPx()+3) self.targetPos[1]=nil self.targetPos[2]=nil end

if(self.targetPos[1]~=nil) then local px = obj1:getPx() if(px<self.targetPos[1]) then px = px+3 if(px>=self.targetPos[1]) then px = self.targetPos[1] self.targetPos[1] = nil end elseif (px>self.targetPos[1]) then px = px-3 if(px<=self.targetPos[1]) then px = self.targetPos[1] self.targetPos[1] = nil end end obj1:setPx(px) end

if(self.targetPos[2]~=nil) then local py = obj1:getPy() if(self.targetPos[2]>py) then py = py+3 if(py>=self.targetPos[2]) then py = self.targetPos[2] self.targetPos[2] = nil end elseif (py>self.targetPos[2]) then py = py-3 if(py<=self.targetPos[2]) then py = self.targetPos[2] self.targetPos[2] = nil end end obj1:setPy(py) end

obj1.sprite:Animate(self.gameFPS) end

function Game:gameUpdate(elapsedTime) self.elapsedTotalStatus = self.elapsedTotalStatus + elapsedTime self.elapsedTotalGraphics = self.elapsedTotalGraphics + elapsedTime

while(tcpIsConnected(s)) do local t = tcpRecv(s) if(t==nil) then break end print(t) end

local nskip = 0 if (self.elapsedTotalGraphics>self.screenFPS) then self:updateGraphics(self.elapsedTotalGraphics) self.elapsedTotalGraphics = self.elapsedTotalGraphics - self.screenFPS while (self.elapsedTotalGraphics>self.screenFPS) do self.elapsedTotalGraphics = self.elapsedTotalGraphics - self.screenFPS nskip=nskip+1 end end

while (self.elapsedTotalStatus>self.gameFPS) do self:updateStatus() self.elapsedTotalStatus = self.elapsedTotalStatus - self.gameFPS end

end

function gameUpdateCB(elapsedTime, data) local game = data

game:gameUpdate(elapsedTime) end

function keysUpdateCB(code, press, data) local game = data

game:keysUpdate(code,press) end

function pointerUpdateCB(but,press,x,y, data) local game = data

game:pointerUpdate(but,press,x,y) end

function Game:init() local cbData = self

initGraphics( GraphicsCallback:new(gameUpdateCB,cbData), KeysCallback:new(keysUpdateCB,cbData), PointerCallback:new(pointerUpdateCB,cbData) ) end

function Game:new() result = {} setmetatable(result, self) self.__index = self

result.gameFPS = 1/30 result.screenFPS = 1/60

return result end

function main() local game = Game:new() game:init() end

main()

< /div> < script type="text/javascript" src="lua+parser.min.js"> < script type="text/javascript" src="lua+parser.js"> < script type="text/javascript" src="graphicsWEB.js"> < script type="text/javascript" src="tcpSocketWEB.js"> < script type="text/javascript"> var divCodeHTML = document.getElementById("divCode").innerHTML; var divCode = document.getElementById("divCode").textContent || document.getElementById("divCode").innerText; var fun = lua_load(divCode,"teste"); var _G = fun(); < /script> < /body> < /html>


graphicsWEB.js (required by main.html):

var timer = null;

var graphicsCB = null; var keysCB = null; var pointerCB = null;

var gameCanvas1EL = document.getElementById("gameCanvas1"); var gameCanvas1 = gameCanvas1EL.getContext('2d');

gameCanvas1EL.onmousedown = function(evt) { var cbData = lua_tableget(pointerCB,"data"); lua_tableget(pointerCB,"callBack")(evt.button,1,(evt.clientX-gameCanvas1EL.offsetLeft),(evt.clientY-gameCanvas1EL.offsetTop),cbData); evt.preventDefault(); evt.stopPropagation(); return false; }

gameCanvas1EL.onmouseup = function(evt) { var cbData = lua_tableget(pointerCB,"data"); lua_tableget(pointerCB,"callBack")(evt.button,0,(evt.clientX-gameCanvas1EL.offsetLeft),(evt.clientY-gameCanvas1EL.offsetTop),cbData); evt.preventDefault(); evt.stopPropagation(); return false; }

document.onkeydown=function(evt) { var cbData = lua_tableget(keysCB,"data"); lua_tableget(keysCB,"callBack")(evt.keyCode,1,cbData); }

document.onkeyup=function(evt) { var cbData = lua_tableget(keysCB,"data"); lua_tableget(keysCB,"callBack")(evt.keyCode,0,cbData); }

lua_core["startFrame"] = function() { }

lua_core["endFrame"] = function() { }

lua_core["clear"] = function() { gameCanvas1.clearRect(0, 0, gameCanvas1EL.width, gameCanvas1EL.height) }

lua_core["drawText"] = function (texto,x,y,wid,fontSize,r,g,b,alpha) { }

lua_core["drawLine"] = function (x1,y1,x2,y2, r,g,b) { }

lua_core["drawImage"] = function (image,x,y) { gameCanvas1.drawImage(image,x,y) }

lua_core["drawImageWithTransparency"] = function(image,x,y,transparency) { gameCanvas1.globalAlpha = transparency; gameCanvas1.drawImage(image,x,y); gameCanvas1.globalAlpha = 1; }

lua_core["initGraphics"] = function(graphics_cb,keys_cb,pointer_cb) { graphicsCB = graphics_cb; keysCB = keys_cb; pointerCB = pointer_cb; timer = setInterval('action()',1); }

lua_core["loadImg"] = function(fname) { var img = new Image(); img.src = fname;

return [img];

}

var lastTime = 0; var currTime = 0; function action() { currTime = new Date(); var cbData = lua_tableget(graphicsCB,"data"); if(lastTime == 0) { lua_tableget(graphicsCB,"callBack")(0,cbData); } else { lua_tableget(graphicsCB,"callBack")( (currTime.getTime() - lastTime.getTime())/1000,cbData); } lastTime=currTime; }


tcpSocketWEB.js (required by main.html):

lua_core["tcpConnect"] = function(address,port) { var ws = new WebSocket('ws://'+address+':'+port); ws.onmessage = function (e) { console.log('Server: ' + e.data); } return ws; }

lua_core["tcpSend"] = function(mySock,data) { /* mySock.send(data);*/ }

lua_core["tcpRecv"] = function(mySock,data) { return null; }

lua_core["tcpIsConnected"] = function(mySock) { return false; }

CarlosEFML commented 11 years ago

please replace spaces in main.html tags

cmwelsh commented 11 years ago

Try loading it into a gist https://gist.github.com/ or indent the entire thing by 4 spaces to use code formatting mode.