Skip to content

Commit f22b034

Browse files
authored
Merge pull request #174 from peterdell/way2js4
Way2js4 - Fix SarLongint for handling FLOAT16
2 parents 797e4ea + 412a40e commit f22b034

File tree

7 files changed

+281
-142
lines changed

7 files changed

+281
-142
lines changed

src/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
*.bak
22
*.exe
3+
*.xex
4+
*.tmp
35
*.log
46
*.lps
57
backup/

src/Makefile.bat

Lines changed: 61 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,11 @@ rem The script will use the FPC, MP and MADS version from there as reference.
77
rem
88
rem The script compiles "Test-0.pas" with FPC vs. the new MP.
99
rem The script compiles a set of reference examples with the released and the new MP an validates that there are no differences in the binary output.
10+
rem The optional first argument to the scrip is "FAST" to only compile the first test.
1011

1112
setlocal
13+
set TEST_MODE=%1
14+
1215
set PATH=%WUDSN_TOOLS_FOLDER%\PAS\FPC.jac;%WUDSN_TOOLS_FOLDER%\ASM\MADS\bin\windows_x86_64;%PATH%
1316
set MP_FOLDER=%~dp0..
1417
set MP_SRC_FOLDER=%MP_FOLDER%\src
@@ -64,48 +67,79 @@ goto :eof
6467
set TEST_MP=%3
6568

6669
set MP_INPUT_PAS=%TEST_MP%.pas
67-
set MP_OUTPUT_ASM=%TEST_MP%.a65
70+
71+
set MP_OUTPUT_ASM_REF=%TEST_MP%-Reference.a65
6872
set MADS_OUTPUT_XEX_REF=%TEST_MP%-Reference.xex
69-
echo %MADS_OUTPUT_XEX_REF%
73+
7074
if %MP%==%WUDSN_MP_EXE% (
75+
set MP_OUTPUT_ASM=%MP_OUTPUT_ASM_REF%
7176
set MADS_OUTPUT_XEX=%MADS_OUTPUT_XEX_REF%
7277
) else (
78+
set MP_OUTPUT_ASM=%TEST_MP%.a65
7379
set MADS_OUTPUT_XEX=%TEST_MP%.xex
7480
)
7581
pushd %TEST_FOLDER%
76-
echo INFO: Compiling "%MP_INPUT_PAS%" in "%TEST_FOLDER%" with "%MP%".
82+
echo INFO: Compiling "%MP_INPUT_PAS%" in "%TEST_FOLDER%" with "%MP%" to "%MP_OUTPUT_ASM%" and "%MADS_OUTPUT_XEX%".
7783
if exist %MP_OUTPUT_ASM% del %MP_OUTPUT_ASM%
78-
%MP% -ipath:%MP_FOLDER%\lib %MP_INPUT_PAS%
84+
%MP% -ipath:%MP_FOLDER%\lib %MP_INPUT_PAS% -o:%MP_OUTPUT_ASM%
7985
if errorlevel 1 goto :mp_error
8086
if exist %MP_OUTPUT_ASM% (
8187
if exist %MADS_OUTPUT_XEX% del %MADS_OUTPUT_XEX%
8288
mads %MP_OUTPUT_ASM% -x -i:%MP_FOLDER%\base -o:%MADS_OUTPUT_XEX%
8389
if exist %MADS_OUTPUT_XEX% (
8490
echo Starting test program "%MADS_OUTPUT_XEX%".
85-
rem %MADS_OUTPUT_XEX%
91+
%MADS_OUTPUT_XEX%
8692
) else (
8793
echo ERROR: MADS output file %MADS_OUTPUT_XEX% not created.
8894
pause
8995
)
9096
) else (
9197
echo ERROR: MP output file %MP_OUTPUT_ASM% not created.
98+
dir *.a65
9299
pause
93100
)
94101

95-
REM TODO Compare file if both files reference exists
96-
if not "%MADS_OUTPUT_XEX%" == "%MADS_OUTPUT_XEX_REF%" (
97-
if exist %MADS_OUTPUT_XEX% (
102+
REM Compare file if both files reference exists
103+
call :compare_files %MP_OUTPUT_ASM% %MP_OUTPUT_ASM_REF% TEXT
104+
call :compare_files %MADS_OUTPUT_XEX% %MADS_OUTPUT_XEX_REF% BINARY
105+
popd
106+
goto :eof
107+
108+
rem Compare file if both files and reference file exist
109+
rem call :compare_files actual_file reference_file mode (TEXT or BINARY)
110+
:compare_files
111+
set COMPARE_CURRENT_FILE=%1
112+
set COMPARE_REFERENCE_FILE=%2
113+
set COMPARE_MODE=%3
114+
if not "%COMPARE_CURRENT_FILE%" == "%COMPARE_REFERENCE_FILE%" (
115+
if exist %COMPARE_CURRENT_FILE% (
98116

99-
if exist %MADS_OUTPUT_XEX_REF% (
100-
fc /b %MADS_OUTPUT_XEX% %MADS_OUTPUT_XEX_REF%
101-
if errorlevel 1 goto :fc_error
117+
if exist %COMPARE_CURRENT_FILE% (
118+
rem echo INFO: Comparing "%COMPARE_CURRENT_FILE%" with "%COMPARE_REFERENCE_FILE%" in mode %COMPARE_MODE%.
119+
if "%COMPARE_MODE%"=="TEXT" (
120+
rem Strip the compiler version difference.
121+
more +2 "%COMPARE_CURRENT_FILE%" > "%COMPARE_CURRENT_FILE%.tmp"
122+
more +2 "%COMPARE_REFERENCE_FILE%" > "%COMPARE_REFERENCE_FILE%.tmp"
123+
fc /L %COMPARE_CURRENT_FILE%.tmp %COMPARE_REFERENCE_FILE%.tmp
124+
if errorlevel 1 (
125+
echo ERROR: "%COMPARE_CURRENT_FILE%" and "%COMPARE_REFERENCE_FILE%" are different.
126+
pause
127+
)
128+
del %COMPARE_CURRENT_FILE%.tmp %COMPARE_REFERENCE_FILE%.tmp
129+
) else (
130+
fc /B %COMPARE_CURRENT_FILE% %COMPARE_REFERENCE_FILE%
131+
if errorlevel 1 (
132+
echo ERROR: "%COMPARE_CURRENT_FILE%" and "%COMPARE_REFERENCE_FILE%" are binary different.
133+
pause
134+
)
135+
)
102136
) else (
103-
echo WARNING: Reference file "%MADS_OUTPUT_XEX_REF%" does not exist, no comparsion possible.
137+
echo WARNING: Reference file "%COMPARE_REFERENCE_FILE%" does not exist, no comparsion possible.
104138
)
105139
)
106140
)
107-
popd
108-
goto :eof
141+
goto :eof
142+
109143

110144
:mp_error
111145
popd
@@ -114,22 +148,18 @@ goto :eof
114148
goto :eof
115149

116150

117-
:fc_error
118-
popd
119-
echo ERROR: %MADS_OUTPUT_XEX% and %MADS_OUTPUT_XEX_REF% are binary different.
120-
pause
121-
goto :eof
122-
123-
rem Run all tests with a given mp.exe.
124-
rem IN: Path to mp.exe
125-
rem
151+
rem Run all tests with a given mp.exe.
152+
rem IN: Path to mp.exe
153+
rem
126154
:run_tests
127-
rem call :run_mp % %MP_SRC_FOLDER% Test-MPP
128-
rem call :run_mp %1=%MP_FOLDER%\samples\a8\games\PacMad pacmadd
129-
call :run_mp %1 %MP_FOLDER%\samples\a8\graph_crossplatform fedorahat
130-
call :run_mp %1 %MP_FOLDER%\samples\a8\graph_crossplatform cannabis
131-
call :run_mp %1 %MP_FOLDER%\samples\a8\graph_crossplatform snowflake
132-
call :run_mp %1 %MP_FOLDER%\samples\a8\graph_crossplatform spline
133-
call :run_mp %1 %MP_FOLDER%\samples\a8\graph_crossplatform fern
134-
goto :eof
155+
call :run_mp %1 %MP_SRC_FOLDER% Test-MP
156+
if "%TEST_MODE%"=="FAST" goto :eof
157+
call :run_mp %1 %MP_FOLDER%\samples\a8\games\PacMad pacmad
158+
call :run_mp %1 %MP_FOLDER%\samples\a8\graph_crossplatform fedorahat
159+
call :run_mp %1 %MP_FOLDER%\samples\a8\graph_crossplatform cannabis
160+
call :run_mp %1 %MP_FOLDER%\samples\a8\graph_crossplatform snowflake
161+
call :run_mp %1 %MP_FOLDER%\samples\a8\graph_crossplatform snowflake_float16
162+
call :run_mp %1 %MP_FOLDER%\samples\a8\graph_crossplatform spline
163+
call :run_mp %1 %MP_FOLDER%\samples\a8\graph_crossplatform fern
164+
goto :eof
135165

src/Numbers.pas

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -80,22 +80,19 @@ procedure MoveTFloat(const ftmp: TFloat; var ConstVal: TNumber); overload;
8080

8181

8282
// ----------------------------------------------------------------------------
83+
// The https://www.freepascal.org/docs-html/rtl/system/sarlongint.html is currently
84+
// missing from the Javascript RTL. The native arithemtic shift right works the same
85+
// for 32-bit operands.
86+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Right_shift
8387
// ----------------------------------------------------------------------------
8488

85-
// https://www.freepascal.org/docs-html/rtl/system/sarlongint.html
86-
function SarLongint(const Value: Longint; const Shift: Byte = 1): Longint;
89+
{$IFDEF PAS2JS}
90+
function SarLongint(const AValue: Longint; const Shift: Byte = 1): Longint;
8791
begin
88-
89-
if Value > 0 then
90-
begin
91-
Result := Value shr Shift;
92-
end
93-
else
94-
begin
95-
Result := -(-Value shr Shift);
96-
end;
92+
asm
93+
return (AValue>>Shift);
9794
end;
98-
95+
{$ENDIF}
9996

10097
// ----------------------------------------------------------------------------
10198
// ----------------------------------------------------------------------------
@@ -279,7 +276,6 @@ function CastToHalfSingle(const a: TNumber): TNumber;
279276

280277
MoveTFloat(a, ftmp);
281278
Result := CardToHalf(ftmp);
282-
283279
end;
284280

285281
function Assign(const valType: Byte; const s: Single): TNumber;

src/Parser.pas

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ interface
1111

1212
function CompileType(i: Integer; out DataType: Byte; out NumAllocElements: cardinal; out AllocElementType: Byte): Integer;
1313

14-
function CompileConstExpression(i: Integer; out ConstVal: Int64; out ConstValType: Byte; VarType: Byte = INTEGERTOK; Err: Boolean = false; War: Boolean = true): Integer;
14+
function CompileConstExpression(i: Integer; out ConstVal: Int64; out ConstValType: Byte; const VarType: Byte = INTEGERTOK; const Err: Boolean = false; const War: Boolean = true): Integer;
1515

1616
function CompileConstTerm(i: Integer; out ConstVal: Int64; out ConstValType: Byte): Integer;
1717

@@ -408,10 +408,9 @@ function CompileConstFactor(i: Integer; out ConstVal: Int64; out ConstValType: B
408408

409409
begin
410410

411-
Result := i;
412-
413411
ConstVal:=0;
414412
ConstValType:=0;
413+
Result := i;
415414

416415
j:=0;
417416

@@ -1143,6 +1142,8 @@ function CompileConstTerm(i: Integer; out ConstVal: Int64; out ConstValType: Byt
11431142
RightConstValType: Byte;
11441143
begin
11451144

1145+
ConstVal:=0;
1146+
ConstValType:=0;
11461147
Result:=i;
11471148

11481149
j := CompileConstFactor(i, ConstVal, ConstValType);
@@ -1227,14 +1228,16 @@ function CompileConstTerm(i: Integer; out ConstVal: Int64; out ConstValType: Byt
12271228
// ----------------------------------------------------------------------------
12281229

12291230

1230-
function CompileSimpleConstExpression(i: Integer; out ConstVal: Int64; out ConstValType: Byte): Integer;
1231+
function CompileSimpleConstExpression(const i: Integer; out ConstVal: Int64; out ConstValType: Byte): Integer;
12311232
var
12321233
j, k: Integer;
12331234
RightConstVal: Int64;
12341235
RightConstValType: Byte;
12351236

12361237
begin
12371238

1239+
ConstVal:=0;
1240+
ConstValType:=0;
12381241
Result:=i;
12391242

12401243
if Tok[i].Kind in [PLUSTOK, MINUSTOK] then j := i + 1 else j := i;
@@ -1304,14 +1307,16 @@ function CompileSimpleConstExpression(i: Integer; out ConstVal: Int64; out Const
13041307
// ----------------------------------------------------------------------------
13051308

13061309

1307-
function CompileConstExpression(i: Integer; out ConstVal: Int64; out ConstValType: Byte; VarType: Byte = INTEGERTOK; Err: Boolean = false; War: Boolean = True): Integer;
1310+
function CompileConstExpression(i: Integer; out ConstVal: Int64; out ConstValType: Byte; const VarType: Byte = INTEGERTOK; const Err: Boolean = false; const War: Boolean = True): Integer;
13081311
var
13091312
j: Integer;
13101313
RightConstVal: Int64;
13111314
RightConstValType: Byte;
13121315
Yes: Boolean;
13131316
begin
13141317

1318+
ConstVal:=0;
1319+
ConstValType:=0;
13151320
Result:=i;
13161321

13171322
i := CompileSimpleConstExpression(i, ConstVal, ConstValType);
@@ -1391,7 +1396,9 @@ procedure DefineIdent(ErrTokenIndex: Integer; Name: TString; Kind: Byte; DataTyp
13911396

13921397
Inc(NumIdent);
13931398

1399+
// For debugging
13941400
// Writeln('NumIdent='+IntToStr(NumIdent)+' ErrTokenIndex='+IntToStr(ErrTokenIndex)+' Name='+name+' Kind='+IntToStr( Kind)+' DataType='+IntToStr( DataType)+' NumAllocElements='+IntToStr( NumAllocElements)+' AllocElementType='+IntToStr( AllocElementType));
1401+
13951402
if NumIdent > High(Ident) then
13961403
Error(NumTok, 'Out of resources, IDENT');
13971404

src/Test-MP.pas

Lines changed: 63 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,70 @@
11
program test;
2-
uses Crt;
32

3+
uses
4+
Crt;
45

5-
procedure Assert(b: Boolean; s: String);
6-
begin
7-
if (b) then
8-
begin
9-
Write('OK: ');
10-
end
11-
else
12-
begin
13-
Write('ERROR:');
14-
end;
15-
Writeln(s);
16-
end;
17-
18-
var i: Integer;
6+
procedure Assert(b: Boolean; s: String); overload;
7+
begin
8+
if (b) then
9+
begin
10+
Write('OK: ');
11+
end
12+
else
13+
begin
14+
Write('ERROR: ');
15+
end;
16+
Writeln(s);
17+
end;
18+
19+
procedure AssertEquals(actual: String; expected: String); overload;
20+
begin
21+
if (actual = expected) then
22+
begin
23+
Writeln('OK: Got ''', actual, ''' = ''', expected, '''.');
24+
end
25+
else
26+
begin
27+
Writeln('ERROR: Got ''', actual, ''' but expected ''', expected, '''.');
28+
end;
29+
end;
30+
31+
procedure TestExpressions;
32+
var
33+
i: Integer;
34+
begin
35+
i := 1;
36+
Writeln('i:=1 equals ', i);
37+
Inc(i);
38+
Writeln('Inc(i) equals ', i);
39+
Assert(i = 2, 'I=2');
40+
Assert(1 + 1 = 2, '1+1=2');
41+
end;
42+
43+
procedure TestFloats;
44+
const
45+
FLOAT16_CONST: Float16 = 0.288675135; { SQRT(3) / 6 }
46+
FLOAT16_CONST_STRING: String = '0.2890';
47+
48+
REAL_CONST: Real = 0.288675135; { SQRT(3) / 6 }
49+
REAL_CONST_STRING: String = '0.2890';
50+
51+
SINGLE_CONST: Single = 0.288675135; { SQRT(3) / 6 }
52+
SINGLE_CONST_STRING: String = '0.2890';
53+
54+
begin
55+
AssertEquals(FloatToStr(FLOAT16_CONST), FLOAT16_CONST_STRING);
56+
AssertEquals(FloatToStr(REAL_CONST), REAL_CONST_STRING);
57+
AssertEquals(FloatToStr(SINGLE_CONST), SINGLE_CONST_STRING);
58+
end;
59+
60+
var
61+
i: Integer;
62+
var
63+
s, msg: String;
1964
begin
20-
i:=1;
21-
Writeln(i);
22-
Inc(i);
23-
Writeln(i);
24-
Assert(i=2, 'I=2');
25-
Assert(1+1=2, '1+1=2');
65+
TestExpressions;
66+
TestFloats;
67+
2668
Writeln('Test completed. Press any key');
2769
repeat
2870
until KeyPressed;

src/TestLanguage.lpi

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,20 @@
4444
<Parsing>
4545
<SyntaxOptions>
4646
<SyntaxMode Value="Delphi"/>
47+
<IncludeAssertionCode Value="True"/>
4748
</SyntaxOptions>
4849
</Parsing>
50+
<CodeGeneration>
51+
<Checks>
52+
<RangeChecks Value="True"/>
53+
<OverflowChecks Value="True"/>
54+
<StackChecks Value="True"/>
55+
</Checks>
56+
<VerifyObjMethodCallValidity Value="True"/>
57+
<Optimizations>
58+
<OptimizationLevel Value="0"/>
59+
</Optimizations>
60+
</CodeGeneration>
4961
<Linking>
5062
<Debugging>
5163
<DebugInfoType Value="dsDwarf2Set"/>

0 commit comments

Comments
 (0)