# HG changeset patch # User unc0rr # Date 1343241963 -14400 # Node ID a46ce1812419c724b6b9fd049ca727443cbfb36e # Parent 6dc7ccc0b043851c24c8abd13cea33ec6482d409# Parent bf80e66d61316aebd14f18ca0128888f4a490b5b merge diff -r bf80e66d6131 -r a46ce1812419 hedgewars/GSHandlers.inc --- a/hedgewars/GSHandlers.inc Wed Jul 25 16:31:34 2012 +0400 +++ b/hedgewars/GSHandlers.inc Wed Jul 25 22:46:03 2012 +0400 @@ -2406,7 +2406,7 @@ //DrawExplosion(gX, gY, 4); if ((GameTicks and $7) = 0) and (Random(2) = 0) then - for i:= 1 to Random(2)+1 do + for i:= Random(2) downto 0 do AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSmoke); if Gear^.Health > 0 then @@ -2420,7 +2420,7 @@ begin DrawExplosion(gX, gY, 4); - for i:= 0 to Random(3) do + for i:= Random(3) downto 0 do AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSmoke); end; @@ -2438,20 +2438,12 @@ if not sticky then begin if ((GameTicks and $3) = 0) and (Random(1) = 0) then - begin - for i:= 1 to Random(2)+1 do - begin + for i:= Random(2) downto 0 do AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSmoke); - end; - end; end else - begin - for i:= 0 to Random(3) do - begin + for i:= Random(3) downto 0 do AddVisualGear(gX - 3 + Random(6), gY - 2, vgtSmoke); - end; - end; DeleteGear(Gear) end; @@ -4398,7 +4390,7 @@ Gear^.State := Gear^.State and (not gstMoving); if (Land[y, x] and lfBouncy <> 0) - or not CalcSlopeTangent(Gear, x, y, tx, ty, 255) + or (not CalcSlopeTangent(Gear, x, y, tx, ty, 255)) or (DistanceI(tx,ty) < _12) then // reject shots at too irregular terrain begin loadNewPortalBall(Gear, true); diff -r bf80e66d6131 -r a46ce1812419 hedgewars/uAI.pas --- a/hedgewars/uAI.pas Wed Jul 25 16:31:34 2012 +0400 +++ b/hedgewars/uAI.pas Wed Jul 25 22:46:03 2012 +0400 @@ -434,7 +434,7 @@ end end; -PGear(Me)^.State:= PGear(Me)^.State and not gstHHThinking; +PGear(Me)^.State:= PGear(Me)^.State and (not gstHHThinking); Think:= 0; InterlockedDecrement(hasThread) end; diff -r bf80e66d6131 -r a46ce1812419 hedgewars/uAIMisc.pas --- a/hedgewars/uAIMisc.pas Wed Jul 25 16:31:34 2012 +0400 +++ b/hedgewars/uAIMisc.pas Wed Jul 25 22:46:03 2012 +0400 @@ -439,21 +439,21 @@ end; if fallDmg < 0 then // drowning. score healthier hogs higher, since their death is more likely to benefit the AI if Score > 0 then - inc(rate, KillScore + Score div 10) // Add a bit of a bonus for bigger hog drownings + inc(rate, (KillScore + Score div 10) * 1024) // Add a bit of a bonus for bigger hog drownings else - dec(rate, KillScore * friendlyfactor div 100 - Score div 10) // and more of a punishment for drowning bigger friendly hogs + dec(rate, (KillScore * friendlyfactor div 100 - Score div 10) * 1024) // and more of a punishment for drowning bigger friendly hogs else if (dmg+fallDmg) >= abs(Score) then if Score > 0 then - inc(rate, KillScore) + inc(rate, KillScore * 1024 + (dmg + fallDmg)) // tiny bonus for dealing more damage than needed to kill else - dec(rate, KillScore * friendlyfactor div 100) + dec(rate, KillScore * friendlyfactor div 100 * 1024) else if Score > 0 then - inc(rate, dmg+fallDmg) - else dec(rate, (dmg+fallDmg) * friendlyfactor div 100) + inc(rate, (dmg + fallDmg) * 1024) + else dec(rate, (dmg + fallDmg) * friendlyfactor div 100 * 1024) end; end; -RateExplosion:= rate * 1024; +RateExplosion:= rate; end; function RateShove(Me: PGear; x, y, r, power, kick: LongInt; gdX, gdY: real; Flags: LongWord): LongInt; @@ -651,7 +651,7 @@ Gear^.Y:= Gear^.Y + Gear^.dY; if (not Gear^.dY.isNegative) and (TestCollisionYwithGear(Gear, 1) <> 0) then begin - Gear^.State:= Gear^.State and not (gstMoving or gstHHJumping); + Gear^.State:= Gear^.State and (not (gstMoving or gstHHJumping)); Gear^.dY:= _0; case JumpType of jmpHJump: @@ -722,7 +722,7 @@ if TestCollisionYwithGear(Gear, 1) <> 0 then begin inc(GoInfo.Ticks, 410); - Gear^.State:= Gear^.State and not (gstMoving or gstHHJumping); + Gear^.State:= Gear^.State and (not (gstMoving or gstHHJumping)); Gear^.dY:= _0; // try ljump instead of fall HHJump(AltGear, jmpLJump, GoInfo); diff -r bf80e66d6131 -r a46ce1812419 hedgewars/uAmmos.pas --- a/hedgewars/uAmmos.pas Wed Jul 25 16:31:34 2012 +0400 +++ b/hedgewars/uAmmos.pas Wed Jul 25 22:46:03 2012 +0400 @@ -374,7 +374,7 @@ with CurWeapon^ do begin s:= trammo[Ammoz[AmmoType].NameId]; - if (Count <> AMMO_INFINITE) and not (Hedgehog.Team^.ExtDriven or (Hedgehog.BotLevel > 0)) then + if (Count <> AMMO_INFINITE) and (not (Hedgehog.Team^.ExtDriven or (Hedgehog.BotLevel > 0))) then s:= s + ' (' + IntToStr(Count) + ')'; if (Propz and ammoprop_Timerable) <> 0 then s:= s + ', ' + IntToStr(Timer div 1000) + ' ' + trammo[sidSeconds]; @@ -386,7 +386,7 @@ end else begin - if Gear <> nil then Gear^.State:= Gear^.State and not gstHHChooseTarget; + if Gear <> nil then Gear^.State:= Gear^.State and (not gstHHChooseTarget); isCursorVisible:= false end; end diff -r bf80e66d6131 -r a46ce1812419 hedgewars/uCommandHandlers.pas --- a/hedgewars/uCommandHandlers.pas Wed Jul 25 16:31:34 2012 +0400 +++ b/hedgewars/uCommandHandlers.pas Wed Jul 25 22:46:03 2012 +0400 @@ -766,7 +766,7 @@ procedure chGameFlags(var s: shortstring); begin GameFlags:= StrToInt(s); -if GameFlags and gfSharedAmmo <> 0 then GameFlags:= GameFlags and not gfPerHogAmmo +if GameFlags and gfSharedAmmo <> 0 then GameFlags:= GameFlags and (not gfPerHogAmmo) end; procedure chHedgehogTurnTime(var s: shortstring); diff -r bf80e66d6131 -r a46ce1812419 hedgewars/uCommands.pas --- a/hedgewars/uCommands.pas Wed Jul 25 16:31:34 2012 +0400 +++ b/hedgewars/uCommands.pas Wed Jul 25 22:46:03 2012 +0400 @@ -95,7 +95,7 @@ begin if TrustedSource or t^.Trusted then begin - if t^.Rand and not CheckNoTeamOrHH then + if t^.Rand and (not CheckNoTeamOrHH) then CheckSum:= CheckSum xor LongWord(SDLNet_Read32(@CmdStr)) xor LongWord(s[0]) xor GameTicks; t^.Handler(s); end; diff -r bf80e66d6131 -r a46ce1812419 hedgewars/uGears.pas --- a/hedgewars/uGears.pas Wed Jul 25 16:31:34 2012 +0400 +++ b/hedgewars/uGears.pas Wed Jul 25 22:46:03 2012 +0400 @@ -211,7 +211,7 @@ RemoveGearFromList(curHandledGear); // since I can't think of any good reason this would ever be separate from a remove from list, going to keep it inside this block if curHandledGear^.Message and gmAddToList <> 0 then InsertGearToList(curHandledGear); - curHandledGear^.Message:= curHandledGear^.Message and not (gmRemoveFromList or gmAddToList) + curHandledGear^.Message:= curHandledGear^.Message and (not (gmRemoveFromList or gmAddToList)) end; if curHandledGear^.Active then begin @@ -634,8 +634,7 @@ if (GameFlags and gfArtillery) <> 0 then cArtillery:= true; - -for i:= 0 to GetRandom(10)+30 do +for i:= GetRandom(10)+30 downto 0 do begin rx:= GetRandom(rightX-leftX)+leftX; ry:= GetRandom(LAND_HEIGHT-topY)+topY; rdx:= _90-(GetRandomf*_360); diff -r bf80e66d6131 -r a46ce1812419 hedgewars/uGearsHedgehog.pas --- a/hedgewars/uGearsHedgehog.pas Wed Jul 25 16:31:34 2012 +0400 +++ b/hedgewars/uGearsHedgehog.pas Wed Jul 25 22:46:03 2012 +0400 @@ -853,7 +853,7 @@ Gear^.State:= Gear^.State and (not gstMoving); exit end; -isFalling:= (Gear^.dY.isNegative) or not TestCollisionYKick(Gear, 1); +isFalling:= (Gear^.dY.isNegative) or (not TestCollisionYKick(Gear, 1)); if isFalling then begin if (Gear^.dY.isNegative) and TestCollisionYKick(Gear, -1) then @@ -983,7 +983,7 @@ begin Gear^.State:= Gear^.State and (not gstWinner); Gear^.State:= Gear^.State and (not gstMoving); - while (TestCollisionYWithGear(Gear,1) = 0) and not CheckGearDrowning(Gear) do + while (TestCollisionYWithGear(Gear,1) = 0) and (not CheckGearDrowning(Gear)) do Gear^.Y:= Gear^.Y+_1; SetLittle(Gear^.dX); Gear^.dY:= _0 diff -r bf80e66d6131 -r a46ce1812419 hedgewars/uGearsUtils.pas --- a/hedgewars/uGearsUtils.pas Wed Jul 25 16:31:34 2012 +0400 +++ b/hedgewars/uGearsUtils.pas Wed Jul 25 22:46:03 2012 +0400 @@ -420,10 +420,9 @@ Scale:= hwFloat2Float(Gear^.Density / _3 * Gear^.dY); if Scale > 1 then Scale:= power(Scale,0.3333) else Scale:= Scale + ((1-Scale) / 2); - if Scale > 1 then Timer:= round(max(Scale,3)) + if Scale > 1 then Timer:= round(min(Scale*0.0005/cGravityf,4)) else Timer:= 1; // Low Gravity - Timer:=round(0.0005/cGravityf); FrameTicks:= FrameTicks*Timer; end; diff -r bf80e66d6131 -r a46ce1812419 hedgewars/uIO.pas --- a/hedgewars/uIO.pas Wed Jul 25 16:31:34 2012 +0400 +++ b/hedgewars/uIO.pas Wed Jul 25 22:46:03 2012 +0400 @@ -402,7 +402,7 @@ TargetPoint.Y:= putY end; AddFileLog('put: ' + inttostr(TargetPoint.X) + ', ' + inttostr(TargetPoint.Y)); - State:= State and not gstHHChooseTarget; + State:= State and (not gstHHChooseTarget); if (Ammoz[CurAmmoType].Ammo.Propz and ammoprop_AttackingPut) <> 0 then Message:= Message or (gmAttack and InputMask); end diff -r bf80e66d6131 -r a46ce1812419 hedgewars/uInputHandler.pas --- a/hedgewars/uInputHandler.pas Wed Jul 25 16:31:34 2012 +0400 +++ b/hedgewars/uInputHandler.pas Wed Jul 25 22:46:03 2012 +0400 @@ -25,8 +25,9 @@ procedure initModule; procedure freeModule; -function KeyNameToCode(name: shortstring; Modifier: shortstring = ''): LongInt; -procedure MaskModifier(var code: LongInt; modifier: LongWord); +function KeyNameToCode(name: shortstring): LongInt; inline; +function KeyNameToCode(name: shortstring; Modifier: shortstring): LongInt; +//procedure MaskModifier(var code: LongInt; modifier: LongWord); procedure MaskModifier(Modifier: shortstring; var code: LongInt); procedure ProcessMouse(event: TSDL_MouseButtonEvent; ButtonDown: boolean); procedure ProcessKey(event: TSDL_KeyboardEvent); inline; @@ -60,6 +61,11 @@ KeyNames: array [0..cKeyMaxIndex] of string[15]; CurrentBinds: TBinds; +function KeyNameToCode(name: shortstring): LongInt; inline; +begin + KeyNameToCode:= KeyNameToCode(name, ''); +end; + function KeyNameToCode(name: shortstring; Modifier: shortstring): LongInt; var code: LongInt; begin @@ -70,7 +76,7 @@ MaskModifier(Modifier, code); KeyNameToCode:= code; end; - +(* procedure MaskModifier(var code: LongInt; Modifier: LongWord); begin if(Modifier and KMOD_LSHIFT) <> 0 then code:= code or LSHIFT; @@ -80,7 +86,7 @@ if(Modifier and KMOD_LCTRL) <> 0 then code:= code or LCTRL; if(Modifier and KMOD_RCTRL) <> 0 then code:= code or LCTRL; end; - +*) procedure MaskModifier(Modifier: shortstring; var code: LongInt); var mod_ : shortstring; ModifierCount, i: LongInt; @@ -133,7 +139,7 @@ if CurrentBinds[code][0] <> #0 then begin - if (code > 3) and KeyDown and not ((CurrentBinds[code] = 'put') or (CurrentBinds[code] = 'ammomenu') or (CurrentBinds[code] = '+cur_u') or (CurrentBinds[code] = '+cur_d') or (CurrentBinds[code] = '+cur_l') or (CurrentBinds[code] = '+cur_r')) then hideAmmoMenu:= true; + if (code > 3) and KeyDown and (not ((CurrentBinds[code] = 'put')) or (CurrentBinds[code] = 'ammomenu') or (CurrentBinds[code] = '+cur_u') or (CurrentBinds[code] = '+cur_d') or (CurrentBinds[code] = '+cur_l') or (CurrentBinds[code] = '+cur_r')) then hideAmmoMenu:= true; if KeyDown then begin diff -r bf80e66d6131 -r a46ce1812419 hedgewars/uScript.pas --- a/hedgewars/uScript.pas Wed Jul 25 16:31:34 2012 +0400 +++ b/hedgewars/uScript.pas Wed Jul 25 22:46:03 2012 +0400 @@ -981,7 +981,7 @@ begin prevgear := CurrentHedgehog^.Gear; prevgear^.Active := false; - prevgear^.State:= prevgear^.State and not gstHHDriven; + prevgear^.State:= prevgear^.State and (not gstHHDriven); prevgear^.Z := cHHZ; prevgear^.Message:= prevgear^.Message or gmRemoveFromList or gmAddToList; diff -r bf80e66d6131 -r a46ce1812419 hedgewars/uSound.pas --- a/hedgewars/uSound.pas Wed Jul 25 16:31:34 2012 +0400 +++ b/hedgewars/uSound.pas Wed Jul 25 22:46:03 2012 +0400 @@ -587,11 +587,8 @@ RegisterVariable('mute' , @chMute , true ); MusicFN:=''; - isMusicEnabled:= true; - isSoundEnabled:= true; isAudioMuted:= false; isSEBackup:= isSoundEnabled; - cInitVolume:= 100; Volume:= 0; defVoicepack:= AskForVoicepack('Default'); @@ -615,6 +612,11 @@ begin if isSoundEnabled then ReleaseSound(true); + // koda still needs to fix this properly. when he rearranged things, he made these variables get + // reset after argparsers picks them up + isMusicEnabled:= true; + isSoundEnabled:= true; + cInitVolume:= 100; end; end. diff -r bf80e66d6131 -r a46ce1812419 hedgewars/uTeams.pas --- a/hedgewars/uTeams.pas Wed Jul 25 16:31:34 2012 +0400 +++ b/hedgewars/uTeams.pas Wed Jul 25 22:46:03 2012 +0400 @@ -473,7 +473,7 @@ begin Gear^.Invulnerable:= false; Gear^.Damage:= Gear^.Health; - Gear^.State:= (Gear^.State or gstHHGone) and not gstHHDriven + Gear^.State:= (Gear^.State or gstHHGone) and (not gstHHDriven) end end end; diff -r bf80e66d6131 -r a46ce1812419 hedgewars/uVisualGears.pas --- a/hedgewars/uVisualGears.pas Wed Jul 25 16:31:34 2012 +0400 +++ b/hedgewars/uVisualGears.pas Wed Jul 25 22:46:03 2012 +0400 @@ -295,6 +295,8 @@ dy:= 0; FrameTicks:= 740; Frame:= 19; + Scale:= 0.75; + Timer:= 1; end; vgtDroplet: begin diff -r bf80e66d6131 -r a46ce1812419 hedgewars/uWorld.pas --- a/hedgewars/uWorld.pas Wed Jul 25 16:31:34 2012 +0400 +++ b/hedgewars/uWorld.pas Wed Jul 25 22:46:03 2012 +0400 @@ -1329,7 +1329,7 @@ r.w:= 3; DrawTextureFromRect(TeamHealthBarWidth + 16, cScreenHeight + DrawHealthY + smallScreenOffset, @r, HealthTex); - if not highlight and not hasGone and (TeamHealth > 1) then + if not highlight and (not hasGone) and (TeamHealth > 1) then for i:= 0 to cMaxHHIndex do if Hedgehogs[i].Gear <> nil then begin diff -r bf80e66d6131 -r a46ce1812419 tools/PascalParser.hs --- a/tools/PascalParser.hs Wed Jul 25 16:31:34 2012 +0400 +++ b/tools/PascalParser.hs Wed Jul 25 22:46:03 2012 +0400 @@ -19,7 +19,7 @@ pascalUnit = do comments - u <- choice [program, unit, systemUnit] + u <- choice [program, unit, systemUnit, redoUnit] comments return u @@ -348,36 +348,46 @@ comments return $ Implementation u (TypesAndVars tv) -expression = buildExpressionParser table term "expression" +expression = do + buildExpressionParser table term "expression" where term = comments >> choice [ builtInFunction expression >>= \(n, e) -> return $ BuiltInFunCall e (SimpleReference (Identifier n BTUnknown)) , try (parens pas $ expression >>= \e -> notFollowedBy (comments >> char '.') >> return e) , brackets pas (commaSep pas iD) >>= return . SetExpression - , try $ natural pas >>= \i -> notFollowedBy (char '.') >> (return . NumberLiteral . show) i + , try $ integer pas >>= \i -> notFollowedBy (char '.') >> (return . NumberLiteral . show) i , float pas >>= return . FloatLiteral . show - , natural pas >>= return . NumberLiteral . show + , try $ integer pas >>= return . NumberLiteral . show , try (string "_S" >> stringLiteral pas) >>= return . StringLiteral , try (string "_P" >> stringLiteral pas) >>= return . PCharLiteral , stringLiteral pas >>= return . strOrChar , try (string "#$") >> many hexDigit >>= \c -> comments >> return (HexCharCode c) , char '#' >> many digit >>= \c -> comments >> return (CharCode c) , char '$' >> many hexDigit >>= \h -> comments >> return (HexNumber h) - , char '-' >> expression >>= return . PrefixOp "-" + --, char '-' >> expression >>= return . PrefixOp "-" + , char '-' >> reference >>= return . PrefixOp "-" . Reference + , try $ string "not" >> error "unexpected not in term" , try $ string "nil" >> return Null - , try $ string "not" >> expression >>= return . PrefixOp "not" , reference >>= return . Reference ] "simple expression" - table = [ + table = [ + [ Prefix (try (string "not") >> return (PrefixOp "not")) + , Prefix (try (char '-') >> return (PrefixOp "-"))] + , [ Infix (char '*' >> return (BinOp "*")) AssocLeft , Infix (char '/' >> return (BinOp "/")) AssocLeft , Infix (try (string "div") >> return (BinOp "div")) AssocLeft , Infix (try (string "mod") >> return (BinOp "mod")) AssocLeft , Infix (try (string "in") >> return (BinOp "in")) AssocNone + , Infix (try $ string "and" >> return (BinOp "and")) AssocLeft + , Infix (try $ string "shl" >> return (BinOp "shl")) AssocLeft + , Infix (try $ string "shr" >> return (BinOp "shr")) AssocLeft ] , [ Infix (char '+' >> return (BinOp "+")) AssocLeft , Infix (char '-' >> return (BinOp "-")) AssocLeft + , Infix (try $ string "or" >> return (BinOp "or")) AssocLeft + , Infix (try $ string "xor" >> return (BinOp "xor")) AssocLeft ] , [ Infix (try (string "<>") >> return (BinOp "<>")) AssocNone , Infix (try (string "<=") >> return (BinOp "<=")) AssocNone @@ -385,13 +395,13 @@ , Infix (char '<' >> return (BinOp "<")) AssocNone , Infix (char '>' >> return (BinOp ">")) AssocNone ] - , [ Infix (try $ string "shl" >> return (BinOp "shl")) AssocNone - , Infix (try $ string "shr" >> return (BinOp "shr")) AssocNone + {-, [ Infix (try $ string "shl" >> return (BinOp "shl")) AssocNone + , Infix (try $ string "shr" >> return (BinOp "shr")) AssocNone ] - , [ Infix (try $ string "and" >> return (BinOp "and")) AssocLeft - , Infix (try $ string "or" >> return (BinOp "or")) AssocLeft + , [ + Infix (try $ string "or" >> return (BinOp "or")) AssocLeft , Infix (try $ string "xor" >> return (BinOp "xor")) AssocLeft - ] + ]-} , [ Infix (char '=' >> return (BinOp "=")) AssocNone ] @@ -415,7 +425,7 @@ , switchCase , withBlock , forCycle - , (try $ reference >>= \r -> string ":=" >> return r) >>= \r -> expression >>= return . Assignment r + , (try $ reference >>= \r -> string ":=" >> return r) >>= \r -> comments >> expression >>= return . Assignment r , builtInFunction expression >>= \(n, e) -> return $ BuiltInFunctionCall e (SimpleReference (Identifier n BTUnknown)) , procCall , char ';' >> comments >> return NOP @@ -480,7 +490,12 @@ comments e1 <- expression comments - choice [string "to", string "downto"] + up <- liftM (== Just "to") $ + optionMaybe $ choice [ + try $ string "to" + , try $ string "downto" + ] + --choice [string "to", string "downto"] comments e2 <- expression comments @@ -488,7 +503,7 @@ comments p <- phrase comments - return $ ForCycle i e1 e2 p + return $ ForCycle i e1 e2 p up switchCase = do try $ string "case" @@ -573,14 +588,20 @@ table = [ [ Prefix (char '-' >> return (InitPrefixOp "-")) + ,Prefix (try (string "not") >> return (InitPrefixOp "not")) ] , [ Infix (char '*' >> return (InitBinOp "*")) AssocLeft , Infix (char '/' >> return (InitBinOp "/")) AssocLeft , Infix (try (string "div") >> return (InitBinOp "div")) AssocLeft , Infix (try (string "mod") >> return (InitBinOp "mod")) AssocLeft + , Infix (try $ string "and" >> return (InitBinOp "and")) AssocLeft + , Infix (try $ string "shl" >> return (InitBinOp "shl")) AssocNone + , Infix (try $ string "shr" >> return (InitBinOp "shr")) AssocNone ] , [ Infix (char '+' >> return (InitBinOp "+")) AssocLeft , Infix (char '-' >> return (InitBinOp "-")) AssocLeft + , Infix (try $ string "or" >> return (InitBinOp "or")) AssocLeft + , Infix (try $ string "xor" >> return (InitBinOp "xor")) AssocLeft ] , [ Infix (try (string "<>") >> return (InitBinOp "<>")) AssocNone , Infix (try (string "<=") >> return (InitBinOp "<=")) AssocNone @@ -589,14 +610,14 @@ , Infix (char '>' >> return (InitBinOp ">")) AssocNone , Infix (char '=' >> return (InitBinOp "=")) AssocNone ] - , [ Infix (try $ string "and" >> return (InitBinOp "and")) AssocLeft + {--, [ Infix (try $ string "and" >> return (InitBinOp "and")) AssocLeft , Infix (try $ string "or" >> return (InitBinOp "or")) AssocLeft , Infix (try $ string "xor" >> return (InitBinOp "xor")) AssocLeft ] , [ Infix (try $ string "shl" >> return (InitBinOp "shl")) AssocNone , Infix (try $ string "shr" >> return (InitBinOp "shr")) AssocNone - ] - , [Prefix (try (string "not") >> return (InitPrefixOp "not"))] + ]--} + --, [Prefix (try (string "not") >> return (InitPrefixOp "not"))] ] itypeCast = do @@ -621,3 +642,14 @@ string "var" v <- varsDecl True return $ System (t ++ v) + +redoUnit = do + string "redo;" + comments + string "type" + comments + t <- typesDecl + string "var" + v <- varsDecl True + return $ Redo (t ++ v) + diff -r bf80e66d6131 -r a46ce1812419 tools/PascalPreprocessor.hs --- a/tools/PascalPreprocessor.hs Wed Jul 25 16:31:34 2012 +0400 +++ b/tools/PascalPreprocessor.hs Wed Jul 25 22:46:03 2012 +0400 @@ -18,6 +18,8 @@ initDefines = Map.fromList [ ("FPC", "") , ("PAS2C", "") + , ("ENDIAN_LITTLE", "") + , ("S3D_DISABLED", "") ] preprocess :: String -> IO String diff -r bf80e66d6131 -r a46ce1812419 tools/PascalUnitSyntaxTree.hs --- a/tools/PascalUnitSyntaxTree.hs Wed Jul 25 16:31:34 2012 +0400 +++ b/tools/PascalUnitSyntaxTree.hs Wed Jul 25 22:46:03 2012 +0400 @@ -7,6 +7,7 @@ Program Identifier Implementation Phrase | Unit Identifier Interface Implementation (Maybe Initialize) (Maybe Finalize) | System [TypeVarDeclaration] + | Redo [TypeVarDeclaration] deriving Show data Interface = Interface Uses TypesAndVars deriving Show @@ -48,7 +49,7 @@ | IfThenElse Expression Phrase (Maybe Phrase) | WhileCycle Expression Phrase | RepeatCycle Expression [Phrase] - | ForCycle Identifier Expression Expression Phrase + | ForCycle Identifier Expression Expression Phrase Bool -- The last Boolean indicates wether it's up or down counting | WithBlock Reference Phrase | Phrases [Phrase] | SwitchCase Expression [([InitExpression], Phrase)] (Maybe [Phrase]) diff -r bf80e66d6131 -r a46ce1812419 tools/pas2c.hs --- a/tools/pas2c.hs Wed Jul 25 16:31:34 2012 +0400 +++ b/tools/pas2c.hs Wed Jul 25 22:46:03 2012 +0400 @@ -71,13 +71,14 @@ escapeChar :: Char -> ShowS escapeChar '"' s = "\\\"" ++ s +escapeChar '\\' s = "\\\\" ++ s escapeChar a s = a : s strInit :: String -> Doc strInit a = text "STRINIT" <> parens (doubleQuotes (text $ escapeStr a)) renderStringConsts :: State RenderState Doc -renderStringConsts = liftM (vcat . map (\(a, b) -> text "const string255" <+> (text a) <+> text "=" <+> strInit b <> semi)) +renderStringConsts = liftM (vcat . map (\(a, b) -> text "static const string255" <+> (text a) <+> text "=" <+> strInit b <> semi)) $ gets stringConsts docToLower :: Doc -> Doc @@ -132,10 +133,16 @@ where f = do checkDuplicateFunDecls tvs - mapM_ (tvar2C True) tvs + mapM_ (tvar2C True False True False) tvs + toNamespace nss (Redo tvs) = -- functions that are re-implemented, add prefix to all of them + currentScope $ execState f (emptyState nss){currentUnit = "fpcrtl_"} + where + f = do + checkDuplicateFunDecls tvs + mapM_ (tvar2C True False True False) tvs toNamespace _ (Program {}) = Map.empty toNamespace nss (Unit (Identifier i _) interface _ _ _) = - currentScope $ execState (interface2C interface) (emptyState nss){currentUnit = map toLower i ++ "_"} + currentScope $ execState (interface2C interface True) (emptyState nss){currentUnit = map toLower i ++ "_"} withState' :: (RenderState -> RenderState) -> State RenderState a -> State RenderState a @@ -149,7 +156,6 @@ }) return a -withLastIdNamespace :: State RenderState Doc -> State RenderState Doc withLastIdNamespace f = do li <- gets lastIdentifier nss <- gets namespaces @@ -165,49 +171,57 @@ toCFiles :: Map.Map String Records -> (String, PascalUnit) -> IO () toCFiles _ (_, System _) = return () +toCFiles _ (_, Redo _) = return () toCFiles ns p@(fn, pu) = do hPutStrLn stdout $ "Rendering '" ++ fn ++ "'..." toCFiles' p where - toCFiles' (fn, p@(Program {})) = writeFile (fn ++ ".c") $ (render2C initialState . pascal2C) p + toCFiles' (fn, p@(Program {})) = writeFile (fn ++ ".c") $ "#include \"fpcrtl.h\"\n" ++ (render2C initialState . pascal2C) p toCFiles' (fn, (Unit unitId@(Identifier i _) interface implementation _ _)) = do - let (a, s) = runState (id2C IOInsert (setBaseType BTUnit unitId) >> interface2C interface) initialState{currentUnit = map toLower i ++ "_"} + let (a, s) = runState (id2C IOInsert (setBaseType BTUnit unitId) >> interface2C interface True) initialState{currentUnit = map toLower i ++ "_"} + (a', s') = runState (id2C IOInsert (setBaseType BTUnit unitId) >> interface2C interface False) initialState{currentUnit = map toLower i ++ "_"} writeFile (fn ++ ".h") $ "#pragma once\n\n#include \"pas2c.h\"\n\n" ++ (render (a $+$ text "")) - writeFile (fn ++ ".c") $ "#include \"" ++ fn ++ ".h\"\n" ++ (render2C s . implementation2C) implementation + writeFile (fn ++ ".c") $ "#include \"fpcrtl.h\"\n\n#include \"" ++ fn ++ ".h\"\n" ++ render (a' $+$ text "") ++ (render2C s . implementation2C) implementation initialState = emptyState ns render2C :: RenderState -> State RenderState Doc -> String render2C a = render . ($+$ empty) . flip evalState a + usesFiles :: PascalUnit -> [String] -usesFiles (Program _ (Implementation uses _) _) = "pas2cSystem" : uses2List uses -usesFiles (Unit _ (Interface uses1 _) (Implementation uses2 _) _ _) = "pas2cSystem" : uses2List uses1 ++ uses2List uses2 +usesFiles (Program _ (Implementation uses _) _) = ["pas2cSystem", "pas2cRedo"] ++ uses2List uses +usesFiles (Unit _ (Interface uses1 _) (Implementation uses2 _) _ _) = ["pas2cSystem", "pas2cRedo"] ++ uses2List uses1 ++ uses2List uses2 usesFiles (System {}) = [] - +usesFiles (Redo {}) = [] pascal2C :: PascalUnit -> State RenderState Doc pascal2C (Unit _ interface implementation init fin) = - liftM2 ($+$) (interface2C interface) (implementation2C implementation) + liftM2 ($+$) (interface2C interface True) (implementation2C implementation) pascal2C (Program _ implementation mainFunction) = do impl <- implementation2C implementation - [main] <- tvar2C True - (FunctionDeclaration (Identifier "main" BTInt) (SimpleType $ Identifier "int" BTInt) [] (Just (TypesAndVars [], mainFunction))) + [main] <- tvar2C True False True True (FunctionDeclaration (Identifier "main" BTInt) (SimpleType $ Identifier "int" BTInt) [VarDeclaration False False ([Identifier "argc" BTInt], SimpleType (Identifier "Integer" BTInt)) Nothing, VarDeclaration False False ([Identifier "argv" BTUnknown], SimpleType (Identifier "PPChar" BTUnknown)) Nothing] (Just (TypesAndVars [], mainFunction))) return $ impl $+$ main - -interface2C :: Interface -> State RenderState Doc -interface2C (Interface uses tvars) = do +-- the second bool indicates whether do normal interface translation or generate variable declarations +-- that will be inserted into implementation files +interface2C :: Interface -> Bool -> State RenderState Doc +interface2C (Interface uses tvars) True = do u <- uses2C uses - tv <- typesAndVars2C True tvars + tv <- typesAndVars2C True True True tvars r <- renderStringConsts return (u $+$ r $+$ tv) +interface2C (Interface uses tvars) False = do + u <- uses2C uses + tv <- typesAndVars2C True False False tvars + r <- renderStringConsts + return tv implementation2C :: Implementation -> State RenderState Doc implementation2C (Implementation uses tvars) = do u <- uses2C uses - tv <- typesAndVars2C True tvars + tv <- typesAndVars2C True False True tvars r <- renderStringConsts return (u $+$ r $+$ tv) @@ -220,17 +234,22 @@ ins (FunctionDeclaration (Identifier i _) _ _ _) m = Map.insertWith (+) (map toLower i) 1 m ins _ m = m -typesAndVars2C :: Bool -> TypesAndVars -> State RenderState Doc -typesAndVars2C b (TypesAndVars ts) = do +-- the second bool indicates whether declare variable as extern or not +-- the third bool indicates whether include types or not + +typesAndVars2C :: Bool -> Bool -> Bool -> TypesAndVars -> State RenderState Doc +typesAndVars2C b externVar includeType(TypesAndVars ts) = do checkDuplicateFunDecls ts - liftM (vcat . map (<> semi) . concat) $ mapM (tvar2C b) ts + liftM (vcat . map (<> semi) . concat) $ mapM (tvar2C b externVar includeType False) ts setBaseType :: BaseType -> Identifier -> Identifier setBaseType bt (Identifier i _) = Identifier i bt uses2C :: Uses -> State RenderState Doc uses2C uses@(Uses unitIds) = do + mapM_ injectNamespace (Identifier "pas2cSystem" undefined : unitIds) + mapM_ injectNamespace (Identifier "pas2cRedo" undefined : unitIds) mapM_ (id2C IOInsert . setBaseType BTUnit) unitIds return $ vcat . map (\i -> text $ "#include \"" ++ i ++ ".h\"") $ uses2List uses where @@ -256,6 +275,7 @@ return $ text i' where n = map toLower i + id2C IOLookup i = id2CLookup head i id2C IOLookupLast i = id2CLookup last i id2C (IOLookupFunction params) (Identifier i t) = do @@ -279,7 +299,7 @@ let vv = head $ fromJust v in modify (\s -> s{lastType = snd vv, lastIdentifier = fst vv}) >> (return . text . fst $ vv) id2CLookup :: ([Record] -> Record) -> Identifier -> State RenderState Doc -id2CLookup f (Identifier i _) = do +id2CLookup f (Identifier i t) = do let i' = map toLower i v <- gets $ Map.lookup i' . currentScope lt <- gets lastType @@ -363,7 +383,7 @@ error $ "Dereferencing from non-pointer type " ++ show t ++ "\n" ++ s -functionParams2C params = liftM (hcat . punctuate comma . concat) $ mapM (tvar2C False) params +functionParams2C params = liftM (hcat . punctuate comma . concat) $ mapM (tvar2C False False True True) params numberOfDeclarations :: [TypeVarDeclaration] -> Int numberOfDeclarations = sum . map cnt @@ -421,12 +441,15 @@ (p, ph) <- withState' (\st -> st{currentScope = Map.insertWith un (map toLower rv) [(render res, t')] $ currentScope st , currentFunctionResult = if isVoid then [] else render res}) $ do p <- functionParams2C params - ph <- liftM2 ($+$) (typesAndVars2C False tvars) (phrase2C' phrase) + ph <- liftM2 ($+$) (typesAndVars2C False False True tvars) (phrase2C' phrase) return (p, ph) let phrasesBlock = if isVoid then ph else t empty <+> res <> semi $+$ ph $+$ text "return" <+> res <> semi - - return [(if notDeclared && hasVars then funWithVarsToDefine n params else empty) $+$ + let define = if hasVars then text "#ifndef" <+> text n $+$ funWithVarsToDefine n params $+$ text "#endif" else empty + return [ + define + $+$ + --(if notDeclared && hasVars then funWithVarsToDefine n params else empty) $+$ t empty <+> text (if hasVars then n ++ "__vars" else n) <> parens p $+$ text "{" @@ -443,37 +466,69 @@ fun2C False _ (FunctionDeclaration (Identifier name _) _ _ _) = error $ "nested functions not allowed: " ++ name fun2C _ tv _ = error $ "fun2C: I don't render " ++ show tv -tvar2C :: Bool -> TypeVarDeclaration -> State RenderState [Doc] -tvar2C b f@(FunctionDeclaration (Identifier name _) _ _ _) = - fun2C b name f -tvar2C _ td@(TypeDeclaration i' t) = do +-- the second bool indicates whether declare variable as extern or not +-- the third bool indicates whether include types or not +-- the fourth bool indicates whether ignore initialization or not (basically for dynamic arrays since we cannot do initialization in function params) +tvar2C :: Bool -> Bool -> Bool -> Bool -> TypeVarDeclaration -> State RenderState [Doc] +tvar2C b _ includeType _ f@(FunctionDeclaration (Identifier name _) _ _ _) = do + t <- fun2C b name f + if includeType then return t else return [] +tvar2C _ _ includeType _ td@(TypeDeclaration i' t) = do i <- id2CTyped t i' tp <- type2C t - return [text "typedef" <+> tp i] + return $ if includeType then [text "typedef" <+> tp i] else [] -tvar2C _ (VarDeclaration True _ (ids, t) Nothing) = do +tvar2C _ _ _ _ (VarDeclaration True _ (ids, t) Nothing) = do t' <- liftM ((empty <+>) . ) $ type2C t liftM (map(\i -> t' i)) $ mapM (id2CTyped (VarParamType t)) ids -tvar2C _ (VarDeclaration _ isConst (ids, t) mInitExpr) = do - t' <- liftM (((if isConst then text "const" else empty) <+>) . ) $ type2C t +tvar2C _ externVar includeType ignoreInit (VarDeclaration _ isConst (ids, t) mInitExpr) = do + t' <- liftM (((if isConst then text "static const" else if externVar + then text "extern" + else empty) + <+>) . ) $ type2C t ie <- initExpr mInitExpr lt <- gets lastType case (isConst, lt, ids, mInitExpr) of (True, BTInt, [i], Just _) -> do i' <- id2CTyped t i - return [text "enum" <> braces (i' <+> ie)] + return $ if includeType then [text "enum" <> braces (i' <+> ie)] else [] (True, BTFloat, [i], Just e) -> do i' <- id2CTyped t i ie <- initExpr2C e - return [text "#define" <+> i' <+> parens ie <> text "\n"] + return $ if includeType then [text "#define" <+> i' <+> parens ie <> text "\n"] else [] (_, BTFunction{}, _, Nothing) -> liftM (map(\i -> t' i)) $ mapM (id2CTyped t) ids - _ -> liftM (map(\i -> t' i <+> ie)) $ mapM (id2CTyped t) ids + (_, BTArray r _ _, [i], _) -> do + i' <- id2CTyped t i + ie' <- return $ case (r, mInitExpr, ignoreInit) of + (RangeInfinite, Nothing, False) -> text "= NULL" -- force dynamic array to be initialized as NULL if not initialized at all + (_, _, _) -> ie + result <- liftM (map(\i -> varDeclDecision isConst includeType (t' i) ie')) $ mapM (id2CTyped t) ids + case (r, ignoreInit) of + (RangeInfinite, False) -> + -- if the array is dynamic, add dimension info to it + return $ [dimDecl] ++ result + where + arrayDimStr = show $ arrayDimension t + arrayDimInitExp = text ("={" ++ ".dim = " ++ arrayDimStr ++ ", .a = {0, 0, 0, 0}}") + dimDecl = varDeclDecision isConst includeType (text "fpcrtl_dimension_t" <+> i' <> text "_dimension_info") arrayDimInitExp + + (_, _) -> return result + + _ -> liftM (map(\i -> varDeclDecision isConst includeType (t' i) ie)) $ mapM (id2CTyped t) ids where initExpr Nothing = return $ empty initExpr (Just e) = liftM (text "=" <+>) (initExpr2C e) + varDeclDecision True True varStr expStr = varStr <+> expStr + varDeclDecision False True varStr expStr = if externVar then varStr else varStr <+> expStr + varDeclDecision False False varStr expStr = varStr <+> expStr + varDeclDecision True False varStr expStr = empty + arrayDimension a = case a of + ArrayDecl Nothing t -> let a = arrayDimension t in if a > 3 then error "Dynamic array with dimension > 4 is not supported." else 1 + arrayDimension t + ArrayDecl _ _ -> error "Mixed dynamic array and static array are not supported." + _ -> 0 -tvar2C f (OperatorDeclaration op (Identifier i _) ret params body) = do +tvar2C f _ _ _ (OperatorDeclaration op (Identifier i _) ret params body) = do r <- op2CTyped op (extractTypes params) fun2C f i (FunctionDeclaration r ret params body) @@ -489,6 +544,7 @@ "-" -> "sub" "*" -> "mul" "/" -> "div" + "/(float)" -> "div" "=" -> "eq" "<" -> "lt" ">" -> "gt" @@ -591,7 +647,7 @@ _ -> return $ \a -> i' <+> text "*" <+> a type2C' (PointerTo t) = liftM (\t a -> t (parens $ text "*" <> a)) $ type2C t type2C' (RecordType tvs union) = do - t <- withState' f $ mapM (tvar2C False) tvs + t <- withState' f $ mapM (tvar2C False False True False) tvs u <- unions return $ \i -> text "struct __" <> i <+> lbrace $+$ nest 4 ((vcat . map (<> semi) . concat $ t) $$ u) $+$ rbrace <+> i where @@ -602,7 +658,7 @@ structs <- mapM struct2C a return $ text "union" $+$ braces (nest 4 $ vcat structs) <> semi struct2C tvs = do - t <- withState' f $ mapM (tvar2C False) tvs + t <- withState' f $ mapM (tvar2C False False True False) tvs return $ text "struct" $+$ braces (nest 4 (vcat . map (<> semi) . concat $ t)) <> semi type2C' (RangeType r) = return (text "int" <+>) type2C' (Sequence ids) = do @@ -615,7 +671,7 @@ t' <- type2C t lt <- gets lastType ft <- case lt of - BTFunction {} -> type2C (PointerTo t) + -- BTFunction {} -> type2C (PointerTo t) _ -> return t' r' <- initExpr2C (InitRange r) return $ \i -> ft i <> brackets r' @@ -675,15 +731,26 @@ e <- expr2C expr return $ r <+> text "=" <+> e <> semi _ -> error $ "Assignment to string from " ++ show lt - (BTArray _ _ _, _) -> phrase2C $ - ProcCall (FunCall - [ - Reference $ Address ref - , Reference $ Address $ RefExpression expr - , Reference $ FunCall [expr] (SimpleReference (Identifier "sizeof" BTUnknown)) - ] - (SimpleReference (Identifier "memcpy" BTUnknown)) - ) [] + (BTArray _ _ _, _) -> do + case expr of + Reference er -> do + exprRef <- ref2C er + exprT <- gets lastType + case exprT of + BTArray RangeInfinite _ _ -> + return $ text "FIXME: assign a dynamic array to an array" + BTArray _ _ _ -> phrase2C $ + ProcCall (FunCall + [ + Reference $ ref + , Reference $ RefExpression expr + , Reference $ FunCall [expr] (SimpleReference (Identifier "sizeof" BTUnknown)) + ] + (SimpleReference (Identifier "memcpy" BTUnknown)) + ) [] + _ -> return $ text "FIXME: assign a non-specific value to an array" + + _ -> return $ text "FIXME: dynamic array assignment 2" _ -> do e <- expr2C expr return $ r <+> text "=" <+> e <> semi @@ -704,7 +771,7 @@ ph <- phrase2C p return $ vcat (map (\i -> text "case" <+> i <> colon) . concat $ ies) <> nest 4 (ph $+$ text "break;") - dflt | isNothing mphrase = return [] + dflt | isNothing mphrase = return [text "default: break;"] -- avoid compiler warning | otherwise = do ph <- mapM phrase2C $ fromJust mphrase return [text "default:" <+> nest 4 (vcat ph)] @@ -716,13 +783,15 @@ (BTRecord _ rs) -> withRecordNamespace (render r ++ ".") rs $ phrase2C $ wrapPhrase p a -> do error $ "'with' block referencing non-record type " ++ show a ++ "\n" ++ show wb -phrase2C (ForCycle i' e1' e2' p) = do +phrase2C (ForCycle i' e1' e2' p up) = do i <- id2C IOLookup i' e1 <- expr2C e1' e2 <- expr2C e2' ph <- phrase2C (wrapPhrase p) + cmp <- return $ if up == True then "<=" else ">=" + inc <- return $ if up == True then "++" else "--" return $ - text "for" <> (parens . hsep . punctuate (char ';') $ [i <+> text "=" <+> e1, i <+> text "<=" <+> e2, text "++" <> i]) + text "for" <> (parens . hsep . punctuate (char ';') $ [i <+> text "=" <+> parens e1, i <+> text cmp <+> parens e2, text inc <> i]) $$ ph phrase2C (RepeatCycle e' p') = do @@ -777,12 +846,23 @@ case expr2 of SetExpression set -> do ids <- mapM (id2C IOLookup) set + modify(\s -> s{lastType = BTBool}) return . parens . hcat . punctuate (text " || ") . map (\i -> parens $ e1 <+> text "==" <+> i) $ ids _ -> error "'in' against not set expression" (o, _, _) | o `elem` boolOps -> do modify(\s -> s{lastType = BTBool}) return $ parens e1 <+> text o <+> parens e2 - | otherwise -> return $ parens e1 <+> text o <+> parens e2 + | otherwise -> do + o' <- return $ case o of + "/(float)" -> text "/(float)" -- pascal returns real value + _ -> text o + e1' <- return $ case (o, t1, t2) of + ("-", BTInt, BTInt) -> parens $ text "(int64_t)" <+> parens e1 + _ -> parens e1 + e2' <- return $ case (o, t1, t2) of + ("-", BTInt, BTInt) -> parens $ text "(int64_t)" <+> parens e2 + _ -> parens e2 + return $ e1' <+> o' <+> e2' where boolOps = ["==", "!=", "<", ">", "<=", ">="] expr2C (NumberLiteral s) = do @@ -806,7 +886,12 @@ BTRecord t _ -> do i <- op2CTyped op [SimpleType (Identifier t undefined)] ref2C $ FunCall [expr] (SimpleReference i) - _ -> return $ text (op2C op) <> e + BTBool -> do + o <- return $ case op of + "not" -> text "!" + _ -> text (op2C op) + return $ o <> parens e + _ -> return $ text (op2C op) <> parens e expr2C Null = return $ text "NULL" expr2C (CharCode a) = do modify(\s -> s{lastType = BTChar}) @@ -835,13 +920,13 @@ _ -> error $ "BuiltInFunCall 'high' from " ++ show e ++ "\ntype: " ++ show lt expr2C (BuiltInFunCall [e] (SimpleReference (Identifier "ord" _))) = liftM parens $ expr2C e expr2C (BuiltInFunCall [e] (SimpleReference (Identifier "succ" _))) = liftM (<> text " + 1") $ expr2C e -expr2C (BuiltInFunCall [e] (SimpleReference (Identifier "pred" _))) = liftM (<> text " - 1") $ expr2C e +expr2C (BuiltInFunCall [e] (SimpleReference (Identifier "pred" _))) = liftM (<> text " - (int64_t)1") $ expr2C e expr2C (BuiltInFunCall [e] (SimpleReference (Identifier "length" _))) = do e' <- expr2C e lt <- gets lastType modify (\s -> s{lastType = BTInt}) case lt of - BTString -> return $ text "Length" <> parens e' + BTString -> return $ text "fpcrtl_Length" <> parens e' BTArray RangeInfinite _ _ -> error $ "length() called on variable size array " ++ show e' BTArray (RangeFromTo _ n) _ _ -> initExpr2C (BuiltInFunction "succ" [n]) _ -> error $ "length() called on " ++ show lt @@ -864,7 +949,7 @@ case t of BTFunction _ _ rt -> do modify(\s -> s{lastType = rt}) - return $ i <> parens empty + return $ i <> parens empty --xymeng: removed parens _ -> return $ i ref2CF r@(RecordField (SimpleReference _) (SimpleReference _)) = do i <- ref2C r @@ -962,7 +1047,7 @@ op2C :: String -> String op2C "or" = "|" op2C "and" = "&" -op2C "not" = "!" +op2C "not" = "~" op2C "xor" = "^" op2C "div" = "/" op2C "mod" = "%" @@ -970,5 +1055,6 @@ op2C "shr" = ">>" op2C "<>" = "!=" op2C "=" = "==" +op2C "/" = "/(float)" op2C a = a