# HG changeset patch # User unc0rr # Date 1322748147 -14400 # Node ID 42e9773eedfd909d3fe41f4bd5fd7ce5923cd05b # Parent 2bed5ba1a7ea4725e3d9fd02485f79c38899503e - Improve renderer a bit, disallow nested functions - Start getting rid of nested functions diff -r 2bed5ba1a7ea -r 42e9773eedfd hedgewars/GSHandlers.inc --- a/hedgewars/GSHandlers.inc Thu Dec 01 11:30:06 2011 +0400 +++ b/hedgewars/GSHandlers.inc Thu Dec 01 18:02:27 2011 +0400 @@ -1378,15 +1378,7 @@ end end; -procedure doStepRopeWork(Gear: PGear); -var - HHGear: PGear; - len, tx, ty, nx, ny, ropeDx, ropeDy, mdX, mdY: hwFloat; - lx, ly, cd: LongInt; - haveCollision, - haveDivided: boolean; - -procedure DeleteMe; +procedure RopeDeleteMe(Gear, HHGear: PGear); begin with HHGear^ do begin @@ -1396,7 +1388,7 @@ DeleteGear(Gear) end; -procedure WaitCollision; +procedure RopeWaitCollision(Gear, HHGear: PGear); begin with HHGear^ do begin @@ -1408,6 +1400,14 @@ Gear^.doStep := @doStepRopeAfterAttack end; +procedure doStepRopeWork(Gear: PGear); +var + HHGear: PGear; + len, tx, ty, nx, ny, ropeDx, ropeDy, mdX, mdY: hwFloat; + lx, ly, cd: LongInt; + haveCollision, + haveDivided: boolean; + begin HHGear := Gear^.Hedgehog^.Gear; @@ -1415,7 +1415,7 @@ or (CheckGearDrowning(HHGear)) then begin PlaySound(sndRopeRelease); - DeleteMe; + RopeDeleteMe(Gear, HHGear); exit end; @@ -1629,9 +1629,9 @@ begin PlaySound(sndRopeRelease); if CurAmmoType <> amParachute then - WaitCollision + RopeWaitCollision(Gear, HHGear) else - DeleteMe + RopeDeleteMe(Gear, HHGear) end end else @@ -1639,12 +1639,7 @@ Gear^.State := Gear^.State or gsttmpFlag; end; -procedure doStepRopeAttach(Gear: PGear); -var - HHGear: PGear; - tx, ty, tt: hwFloat; - -procedure RemoveFromAmmo; +procedure RopeRemoveFromAmmo(Gear, HHGear: PGear); begin if (Gear^.State and gstAttacked) = 0 then begin @@ -1654,6 +1649,10 @@ ApplyAmmoChanges(HHGear^.Hedgehog^) end; +procedure doStepRopeAttach(Gear: PGear); +var + HHGear: PGear; + tx, ty, tt: hwFloat; begin Gear^.X := Gear^.X - Gear^.dX; Gear^.Y := Gear^.Y - Gear^.dY; @@ -1702,7 +1701,7 @@ Message := Message and (not gmAttack) end; - RemoveFromAmmo; + RopeRemoveFromAmmo(Gear, HHGear); tt := _0; exit @@ -1728,7 +1727,7 @@ Message := Message and (not gmAttack) end; - RemoveFromAmmo; + RopeRemoveFromAmmo(Gear, HHGear); exit end; diff -r 2bed5ba1a7ea -r 42e9773eedfd hedgewars/uAIActions.pas --- a/hedgewars/uAIActions.pas Thu Dec 01 11:30:06 2011 +0400 +++ b/hedgewars/uAIActions.pas Thu Dec 01 18:02:27 2011 +0400 @@ -119,28 +119,27 @@ end end; +procedure CheckHang(Me: PGear); +const PrevX: LongInt = 0; + timedelta: Longword = 0; +begin +if hwRound(Me^.X) <> PrevX then + begin + PrevX:= hwRound(Me^.X); + timedelta:= 0 + end else + begin + inc(timedelta); + if timedelta > 1700 then + begin + timedelta:= 0; + FreeActionsList + end + end +end; + procedure ProcessAction(var Actions: TActions; Me: PGear); var s: shortstring; - - procedure CheckHang; - const PrevX: LongInt = 0; - timedelta: Longword = 0; - begin - if hwRound(Me^.X) <> PrevX then - begin - PrevX:= hwRound(Me^.X); - timedelta:= 0 - end else - begin - inc(timedelta); - if timedelta > 1700 then - begin - timedelta:= 0; - FreeActionsList - end - end - end; - begin repeat if Actions.Pos >= Actions.Count then exit; @@ -165,7 +164,7 @@ FreeActionsList; exit end - else begin CheckHang; exit end; + else begin CheckHang(Me); exit end; aia_WaitXR: if hwRound(Me^.X) = Param then begin Action:= aia_LookRight; @@ -178,7 +177,7 @@ FreeActionsList; exit end - else begin CheckHang; exit end; + else begin CheckHang(Me); exit end; aia_LookLeft: if not Me^.dX.isNegative then begin ParseCommand('+left', true); diff -r 2bed5ba1a7ea -r 42e9773eedfd hedgewars/uAIAmmoTests.pas --- a/hedgewars/uAIAmmoTests.pas Thu Dec 01 11:30:06 2011 +0400 +++ b/hedgewars/uAIAmmoTests.pas Thu Dec 01 18:02:27 2011 +0400 @@ -124,33 +124,11 @@ function TestBazooka(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; var Vx, Vy, r, mX, mY: real; rTime: LongInt; - Score, EX, EY: LongInt; + EX, EY: LongInt; valueResult: LongInt; - - function CheckTrace: LongInt; - var x, y, dX, dY: real; - t: LongInt; - value: LongInt; - begin - x:= mX; - y:= mY; - dX:= Vx; - dY:= -Vy; - t:= rTime; - repeat - x:= x + dX; - y:= y + dY; - dX:= dX + cWindSpeedf; - dY:= dY + cGravityf; - dec(t) - until TestCollExcludingMe(Me, trunc(x), trunc(y), 5) or (t <= 0); - EX:= trunc(x); - EY:= trunc(y); - value:= RateExplosion(Me, EX, EY, 101); - if value = 0 then value:= - Metric(Targ.X, Targ.Y, EX, EY) div 64; - CheckTrace:= value; - end; - + x, y, dX, dY: real; + t: LongInt; + value: LongInt; begin mX:= hwFloat2Float(Me^.X); mY:= hwFloat2Float(Me^.Y); @@ -165,15 +143,30 @@ r:= sqrt(sqr(Vx) + sqr(Vy)); if not (r > 1) then begin - Score:= CheckTrace; - if valueResult <= Score then + x:= mX; + y:= mY; + dX:= Vx; + dY:= -Vy; + t:= rTime; + repeat + x:= x + dX; + y:= y + dY; + dX:= dX + cWindSpeedf; + dY:= dY + cGravityf; + dec(t) + until TestCollExcludingMe(Me, trunc(x), trunc(y), 5) or (t <= 0); + EX:= trunc(x); + EY:= trunc(y); + value:= RateExplosion(Me, EX, EY, 101); + if value = 0 then value:= - Metric(Targ.X, Targ.Y, EX, EY) div 64; + if valueResult <= value then begin ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random((Level - 1) * 9)); ap.Power:= trunc(r * cMaxPower) - random((Level - 1) * 17 + 1); ap.ExplR:= 100; ap.ExplX:= EX; ap.ExplY:= EY; - valueResult:= Score + valueResult:= value end; end until (rTime > 4250); @@ -183,32 +176,11 @@ function TestSnowball(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; var Vx, Vy, r: hwFloat; rTime: LongInt; - Score, EX, EY: LongInt; + EX, EY: LongInt; valueResult: LongInt; - - function CheckTrace: LongInt; - var x, y, dX, dY: hwFloat; - t: LongInt; - value: LongInt; - begin - x:= Me^.X; - y:= Me^.Y; - dX:= Vx; - dY:= -Vy; - t:= rTime; - repeat - x:= x + dX; - y:= y + dY; - dX:= dX + cWindSpeed; - dY:= dY + cGravity; - dec(t) - until TestCollExcludingMe(Me, hwRound(x), hwRound(y), 5) or (t <= 0); - EX:= hwRound(x); - EY:= hwRound(y); - value:= RateExplosion(Me, EX, EY, 5); - if value = 0 then value:= - Metric(Targ.X, Targ.Y, EX, EY) div 64; - CheckTrace:= value; - end; + x, y, dX, dY: hwFloat; + t: LongInt; + value: LongInt; begin ap.Time:= 0; @@ -222,16 +194,32 @@ r:= Distance(Vx, Vy); if not (r > _1) then begin - Score:= CheckTrace; - if valueResult <= Score then - begin - ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random((Level - 1) * 9)); - ap.Power:= hwRound(r * cMaxPower) - random((Level - 1) * 17 + 1); - ap.ExplR:= 100; - ap.ExplX:= EX; - ap.ExplY:= EY; - valueResult:= Score - end; + x:= Me^.X; + y:= Me^.Y; + dX:= Vx; + dY:= -Vy; + t:= rTime; + repeat + x:= x + dX; + y:= y + dY; + dX:= dX + cWindSpeed; + dY:= dY + cGravity; + dec(t) + until TestCollExcludingMe(Me, hwRound(x), hwRound(y), 5) or (t <= 0); + EX:= hwRound(x); + EY:= hwRound(y); + value:= RateExplosion(Me, EX, EY, 5); + if value = 0 then value:= - Metric(Targ.X, Targ.Y, EX, EY) div 64; + + if valueResult <= value then + begin + ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random((Level - 1) * 9)); + ap.Power:= hwRound(r * cMaxPower) - random((Level - 1) * 17 + 1); + ap.ExplR:= 100; + ap.ExplX:= EX; + ap.ExplY:= EY; + valueResult:= value + end; end until (rTime > 4250); TestSnowball:= valueResult @@ -241,26 +229,8 @@ var Vx, Vy, r: hwFloat; Score, EX, EY, valueResult: LongInt; TestTime: Longword; - - function CheckTrace: LongInt; - var x, y, dY: hwFloat; - t: LongInt; - begin - x:= Me^.X; - y:= Me^.Y; - dY:= -Vy; - t:= TestTime; - repeat - x:= x + Vx; - y:= y + dY; - dY:= dY + cGravity; - dec(t) - until TestCollExcludingMe(Me, hwRound(x), hwRound(y), 7) or (t = 0); - EX:= hwRound(x); - EY:= hwRound(y); - if t < 50 then CheckTrace:= RateExplosion(Me, EX, EY, 97) // average of 17 attempts, most good, but some failing spectacularly - else CheckTrace:= BadTurn - end; + x, y, dY: hwFloat; + t: LongInt; begin valueResult:= BadTurn; TestTime:= 0; @@ -272,17 +242,31 @@ r:= Distance(Vx, Vy); if not (r > _1) then begin - Score:= CheckTrace; - if valueResult < Score then - begin - ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random(Level)); - ap.Power:= hwRound(r * cMaxPower) + AIrndSign(random(Level) * 15); - ap.Time:= TestTime; - ap.ExplR:= 100; - ap.ExplX:= EX; - ap.ExplY:= EY; - valueResult:= Score - end; + x:= Me^.X; + y:= Me^.Y; + dY:= -Vy; + t:= TestTime; + repeat + x:= x + Vx; + y:= y + dY; + dY:= dY + cGravity; + dec(t) + until TestCollExcludingMe(Me, hwRound(x), hwRound(y), 7) or (t = 0); + EX:= hwRound(x); + EY:= hwRound(y); + if t < 50 then Score:= RateExplosion(Me, EX, EY, 97) // average of 17 attempts, most good, but some failing spectacularly + else Score:= BadTurn; + + if valueResult < Score then + begin + ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random(Level)); + ap.Power:= hwRound(r * cMaxPower) + AIrndSign(random(Level) * 15); + ap.Time:= TestTime; + ap.ExplR:= 100; + ap.ExplX:= EX; + ap.ExplY:= EY; + valueResult:= Score + end; end until (TestTime > 4250); TestMolotov:= valueResult @@ -293,26 +277,8 @@ var Vx, Vy, r: hwFloat; Score, EX, EY, valueResult: LongInt; TestTime: Longword; - - function CheckTrace: LongInt; - var x, y, dY: hwFloat; - t: LongInt; - begin - x:= Me^.X; - y:= Me^.Y; - dY:= -Vy; - t:= TestTime; - repeat - x:= x + Vx; - y:= y + dY; - dY:= dY + cGravity; - dec(t) - until TestCollExcludingMe(Me, hwRound(x), hwRound(y), 5) or (t = 0); - EX:= hwRound(x); - EY:= hwRound(y); - if t < 50 then CheckTrace:= RateExplosion(Me, EX, EY, 101) - else CheckTrace:= BadTurn - end; + x, y, dY: hwFloat; + t: LongInt; begin valueResult:= BadTurn; TestTime:= 0; @@ -323,9 +289,25 @@ Vy:= cGravity * ((TestTime + tDelta) div 2) - (int2hwFloat(Targ.Y) - Me^.Y) / int2hwFloat(TestTime + tDelta); r:= Distance(Vx, Vy); if not (r > _1) then - begin - Score:= CheckTrace; - if valueResult < Score then + begin + x:= Me^.X; + y:= Me^.Y; + dY:= -Vy; + t:= TestTime; + repeat + x:= x + Vx; + y:= y + dY; + dY:= dY + cGravity; + dec(t) + until TestCollExcludingMe(Me, hwRound(x), hwRound(y), 5) or (t = 0); + EX:= hwRound(x); + EY:= hwRound(y); + if t < 50 then + Score:= RateExplosion(Me, EX, EY, 101) + else + Score:= BadTurn; + + if valueResult < Score then begin ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random(Level)); ap.Power:= hwRound(r * cMaxPower) + AIrndSign(random(Level) * 15); @@ -335,7 +317,7 @@ ap.ExplY:= EY; valueResult:= Score end; - end + end until (TestTime = 4000); TestGrenade:= valueResult end; @@ -345,26 +327,8 @@ var Vx, Vy, r: hwFloat; Score, EX, EY, valueResult: LongInt; TestTime: Longword; - - function CheckTrace: LongInt; - var x, y, dY: hwFloat; - t: LongInt; - begin - x:= Me^.X; - y:= Me^.Y; - dY:= -Vy; - t:= TestTime; - repeat - x:= x + Vx; - y:= y + dY; - dY:= dY + cGravity; - dec(t) - until TestCollExcludingMe(Me, hwRound(x), hwRound(y), 5) or (t = 0); - EX:= hwRound(x); - EY:= hwRound(y); - if t < 50 then CheckTrace:= RateExplosion(Me, EX, EY, 41) - else CheckTrace:= BadTurn - end; + x, y, dY: hwFloat; + t: LongInt; begin valueResult:= BadTurn; TestTime:= 0; @@ -380,7 +344,23 @@ r:= Distance(Vx, Vy); if not (r > _1) then begin - Score:= CheckTrace; + x:= Me^.X; + y:= Me^.Y; + dY:= -Vy; + t:= TestTime; + repeat + x:= x + Vx; + y:= y + dY; + dY:= dY + cGravity; + dec(t) + until TestCollExcludingMe(Me, hwRound(x), hwRound(y), 5) or (t = 0); + EX:= hwRound(x); + EY:= hwRound(y); + if t < 50 then + Score:= RateExplosion(Me, EX, EY, 41) + else + Score:= BadTurn; + if valueResult < Score then begin ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random(Level)); @@ -401,26 +381,8 @@ var Vx, Vy, r: hwFloat; Score, EX, EY, valueResult: LongInt; TestTime: Longword; - - function CheckTrace: LongInt; - var x, y, dY: hwFloat; - t: LongInt; - begin - x:= Me^.X; - y:= Me^.Y; - dY:= -Vy; - t:= TestTime; - repeat - x:= x + Vx; - y:= y + dY; - dY:= dY + cGravity; - dec(t) - until TestCollExcludingMe(Me, hwRound(x), hwRound(y), 5) or (t = 0); - EX:= hwRound(x); - EY:= hwRound(y); - if t < 50 then CheckTrace:= RateExplosion(Me, EX, EY, 381) - else CheckTrace:= BadTurn - end; + x, y, dY: hwFloat; + t: LongInt; begin valueResult:= BadTurn; TestTime:= 0; @@ -431,9 +393,25 @@ Vy:= cGravity * ((TestTime + tDelta) div 2) - (int2hwFloat(Targ.Y-200) - Me^.Y) / int2hwFloat(TestTime + tDelta); r:= Distance(Vx, Vy); if not (r > _1) then - begin - Score:= CheckTrace; - if valueResult < Score then + begin + x:= Me^.X; + y:= Me^.Y; + dY:= -Vy; + t:= TestTime; + repeat + x:= x + Vx; + y:= y + dY; + dY:= dY + cGravity; + dec(t) + until TestCollExcludingMe(Me, hwRound(x), hwRound(y), 5) or (t = 0); + EX:= hwRound(x); + EY:= hwRound(y); + if t < 50 then + Score:= RateExplosion(Me, EX, EY, 381) + else + Score:= BadTurn; + + if valueResult < Score then begin ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random(Level)); ap.Power:= hwRound(r * cMaxPower * _0_9) + AIrndSign(random(Level) * 15); @@ -443,56 +421,19 @@ ap.ExplY:= EY; valueResult:= Score end; - end + end until (TestTime = 4000); TestWatermelon:= valueResult end; -function TestMortar(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; -//const tDelta = 24; -var Vx, Vy: hwFloat; - Score, EX, EY, valueResult: LongInt; - TestTime: Longword; - function CheckTrace: LongInt; - var x, y, dY: hwFloat; - value: LongInt; - begin - x:= Me^.X; - y:= Me^.Y; - dY:= -Vy; - - repeat - x:= x + Vx; - y:= y + dY; - dY:= dY + cGravity; - EX:= hwRound(x); - EY:= hwRound(y); - until TestCollExcludingMe(Me, EX, EY, 5) or (EY > cWaterLine); - - if (EY < cWaterLine) and (not dY.isNegative) then - begin - value:= RateExplosion(Me, EX, EY, 91); - if (value = 0) then - if (dY > _0_15) then - value:= - abs(Targ.Y - EY) div 32 - else - value:= BadTurn - else if (value < 0) then value:= BadTurn - end - else - value:= BadTurn; - - CheckTrace:= value; - end; - - function Solve: LongWord; + function Solve(TX, TY, MX, MY: LongInt): LongWord; var A, B, D, T: hwFloat; C: LongInt; begin A:= hwSqr(cGravity) * _0_25; - B:= - cGravity * (Targ.Y - hwRound(Me^.Y)) - _1; - C:= sqr(Targ.Y - hwRound(Me^.Y)) + sqr(Targ.X - hwRound(Me^.X)); + B:= - cGravity * (TY - MY) - _1; + C:= sqr(TY - MY) + sqr(TX - MX); D:= hwSqr(B) - (A * C * 4); if D.isNegative = false then begin @@ -504,21 +445,51 @@ Solve:= hwRound(T) end else Solve:= 0 end; - + +function TestMortar(Me: PGear; Targ: TPoint; Level: LongInt; var ap: TAttackParams): LongInt; +//const tDelta = 24; +var Vx, Vy: hwFloat; + Score, EX, EY, valueResult: LongInt; + TestTime: Longword; + x, y, dY: hwFloat; begin valueResult:= BadTurn; ap.ExplR:= 0; if (Level > 2) then exit(BadTurn); -TestTime:= Solve; +TestTime:= Solve(Targ.X, Targ.Y, hwRound(Me^.X), hwRound(Me^.Y)); if TestTime = 0 then exit(BadTurn); Vx:= (int2hwFloat(Targ.X) - Me^.X) / int2hwFloat(TestTime); Vy:= cGravity * (TestTime div 2) - (int2hwFloat(Targ.Y) - Me^.Y) / int2hwFloat(TestTime); - Score:= CheckTrace; + x:= Me^.X; + y:= Me^.Y; + dY:= -Vy; + + repeat + x:= x + Vx; + y:= y + dY; + dY:= dY + cGravity; + EX:= hwRound(x); + EY:= hwRound(y); + until TestCollExcludingMe(Me, EX, EY, 5) or (EY > cWaterLine); + + if (EY < cWaterLine) and (not dY.isNegative) then + begin + Score:= RateExplosion(Me, EX, EY, 91); + if (Score = 0) then + if (dY > _0_15) then + Score:= - abs(Targ.Y - EY) div 32 + else + Score:= BadTurn + else if (Score < 0) then Score:= BadTurn + end + else + Score:= BadTurn; + if valueResult < Score then begin ap.Angle:= DxDy2AttackAngle(Vx, Vy) + AIrndSign(random(Level)); diff -r 2bed5ba1a7ea -r 42e9773eedfd hedgewars/uAIMisc.pas --- a/hedgewars/uAIMisc.pas Thu Dec 01 11:30:06 2011 +0400 +++ b/hedgewars/uAIMisc.pas Thu Dec 01 18:02:27 2011 +0400 @@ -115,20 +115,19 @@ else friendlyfactor:= max(30, 300 - f * 80 div max(1,e)) end; +procedure AddBonus(x, y: LongInt; r: Longword; s: LongInt); +begin +bonuses.ar[bonuses.Count].x:= x; +bonuses.ar[bonuses.Count].y:= y; +bonuses.ar[bonuses.Count].Radius:= r; +bonuses.ar[bonuses.Count].Score:= s; +inc(bonuses.Count); +TryDo(bonuses.Count <= MAXBONUS, 'Bonuses overflow', true) +end; + procedure FillBonuses(isAfterAttack: boolean; filter: TGearsType); var Gear: PGear; MyClan: PClan; - - procedure AddBonus(x, y: LongInt; r: Longword; s: LongInt); - begin - bonuses.ar[bonuses.Count].x:= x; - bonuses.ar[bonuses.Count].y:= y; - bonuses.ar[bonuses.Count].Radius:= r; - bonuses.ar[bonuses.Count].Score:= s; - inc(bonuses.Count); - TryDo(bonuses.Count <= MAXBONUS, 'Bonuses overflow', true) - end; - begin bonuses.Count:= 0; MyClan:= ThinkingHH^.Hedgehog^.Team^.Clan; diff -r 2bed5ba1a7ea -r 42e9773eedfd tools/pas2c.hs --- a/tools/pas2c.hs Thu Dec 01 11:30:06 2011 +0400 +++ b/tools/pas2c.hs Thu Dec 01 18:02:27 2011 +0400 @@ -52,10 +52,14 @@ toCFiles :: (String, PascalUnit) -> IO () toCFiles (_, System) = return () -toCFiles (fn, p@(Program {})) = writeFile (fn ++ ".c") $ (render . pascal2C) p -toCFiles (fn, (Unit _ interface implementation _ _)) = do - writeFile (fn ++ ".h") $ (render . interface2C) interface - writeFile (fn ++ ".c") $ (render . implementation2C) implementation +toCFiles p@(fn, pu) = do + hPutStrLn stderr $ "Rendering '" ++ fn ++ "'..." + toCFiles' p + where + toCFiles' (fn, p@(Program {})) = writeFile (fn ++ ".c") $ (render . pascal2C) p + toCFiles' (fn, (Unit _ interface implementation _ _)) = do + writeFile (fn ++ ".h") $ (render . interface2C) interface + writeFile (fn ++ ".c") $ (render . implementation2C) implementation usesFiles :: PascalUnit -> [String] usesFiles (Program _ (Implementation uses _) _) = uses2List uses @@ -71,18 +75,18 @@ pascal2C (Program _ implementation mainFunction) = implementation2C implementation $+$ - tvar2C (FunctionDeclaration (Identifier "main") (SimpleType $ Identifier "int") [] (Just (TypesAndVars [], mainFunction))) + tvar2C True (FunctionDeclaration (Identifier "main") (SimpleType $ Identifier "int") [] (Just (TypesAndVars [], mainFunction))) interface2C :: Interface -> Doc -interface2C (Interface uses tvars) = uses2C uses $+$ typesAndVars2C tvars +interface2C (Interface uses tvars) = uses2C uses $+$ typesAndVars2C True tvars implementation2C :: Implementation -> Doc -implementation2C (Implementation uses tvars) = uses2C uses $+$ typesAndVars2C tvars +implementation2C (Implementation uses tvars) = uses2C uses $+$ typesAndVars2C True tvars -typesAndVars2C :: TypesAndVars -> Doc -typesAndVars2C (TypesAndVars ts) = vcat $ map tvar2C ts +typesAndVars2C :: Bool -> TypesAndVars -> Doc +typesAndVars2C b (TypesAndVars ts) = vcat $ map (tvar2C b) ts uses2C :: Uses -> Doc uses2C uses = vcat $ map (\i -> text $ "#include \"" ++ i ++ ".h\"") $ uses2List uses @@ -90,15 +94,15 @@ uses2List :: Uses -> [String] uses2List (Uses ids) = map (\(Identifier i) -> i) ids -tvar2C :: TypeVarDeclaration -> Doc -tvar2C (FunctionDeclaration (Identifier name) returnType params Nothing) = - type2C returnType <+> text name <> parens (hcat $ map tvar2C params) <> text ";" -tvar2C (FunctionDeclaration (Identifier name) returnType params (Just (tvars, phrase))) = - type2C returnType <+> text name <> parens (hcat $ map tvar2C params) +tvar2C :: Bool -> TypeVarDeclaration -> Doc +tvar2C _ (FunctionDeclaration (Identifier name) returnType params Nothing) = + type2C returnType <+> text name <> parens (hcat $ map (tvar2C False) params) <> text ";" +tvar2C True (FunctionDeclaration (Identifier name) returnType params (Just (tvars, phrase))) = + type2C returnType <+> text name <> parens (hcat $ map (tvar2C False) params) $+$ text "{" $+$ nest 4 ( - typesAndVars2C tvars + typesAndVars2C False tvars $+$ phrase2C' phrase ) @@ -107,8 +111,9 @@ where phrase2C' (Phrases p) = vcat $ map phrase2C p phrase2C' p = phrase2C p -tvar2C (TypeDeclaration (Identifier i) t) = text "type" <+> text i <+> type2C t <> text ";" -tvar2C (VarDeclaration isConst (ids, t) mInitExpr) = +tvar2C False (FunctionDeclaration (Identifier name) _ _ _) = error $ "nested functions not allowed: " ++ name +tvar2C _ (TypeDeclaration (Identifier i) t) = text "type" <+> text i <+> type2C t <> text ";" +tvar2C _ (VarDeclaration isConst (ids, t) mInitExpr) = if isConst then text "const" else empty <+> type2C t @@ -121,8 +126,8 @@ where initExpr Nothing = empty initExpr (Just e) = text "=" <+> initExpr2C e -tvar2C (OperatorDeclaration op _ ret params body) = - tvar2C (FunctionDeclaration (Identifier "") ret params body) +tvar2C f (OperatorDeclaration op _ ret params body) = + tvar2C f (FunctionDeclaration (Identifier $ "") ret params body) initExpr2C :: InitExpression -> Doc initExpr2C (InitBinOp op expr1 expr2) = parens $ (initExpr2C expr1) <+> op2C op <+> (initExpr2C expr2) @@ -140,7 +145,7 @@ type2C (String l) = text $ "string" ++ show l type2C (SimpleType (Identifier i)) = text i type2C (PointerTo t) = type2C t <> text "*" -type2C (RecordType tvs union) = text "{" $+$ (nest 4 . vcat . map tvar2C $ tvs) $+$ text "}" +type2C (RecordType tvs union) = text "{" $+$ (nest 4 . vcat . map (tvar2C False) $ tvs) $+$ text "}" type2C (RangeType r) = text "<>" type2C (Sequence ids) = text "<>" type2C (ArrayDecl r t) = text "<>"