Skip to content
42 changes: 42 additions & 0 deletions examplescripts/perfect5000.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@

// Some simple testing of new, eval and some string stuff.

// constructor -- expression array initialization
function ExprArray(n,v)
{
// Initializes n values to v coerced to a string.
for (var i = 0; i < n; i++) {
this[i] = "" + v;
}
}


// Print the perfect numbers up to n and the sum expression for n's divisors.
function perfect(n)
{
trace("The perfect numbers up to " + n + " are:");

// We build sumOfDivisors[i] to hold a string expression for
// the sum of the divisors of i, excluding i itself.
var sumOfDivisors = new ExprArray(n+1,1);
for (var divisor = 2; divisor <= n; divisor++) {
for (var j = divisor + divisor; j <= n; j += divisor) {
sumOfDivisors[j] += " + " + divisor;
}
// At this point everything up to 'divisor' has its sumOfDivisors
// expression calculated, so we can determine whether it's perfect
// already by evaluating.
if (eval(sumOfDivisors[divisor]) == divisor) {
trace("" + divisor + " = " + sumOfDivisors[divisor]);
}
}
trace("That's all.");
}


trace("\nA number is 'perfect' if it is equal to the sum of its");
trace("divisors (excluding itself).\n");
var st=(new Date()).valueOf();
perfect(5000);
var et=(new Date()).valueOf();
trace(et-st,' milliseconds');
6 changes: 6 additions & 0 deletions src/BESENConstants.pas
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@
unit BESENConstants;
{$i BESEN.inc}


{$define THRhash}
{$define THRhash2}



interface

uses Math;
Expand Down
7 changes: 4 additions & 3 deletions src/BESENDateUtils.pas
Original file line number Diff line number Diff line change
Expand Up @@ -632,7 +632,7 @@ function BESENParseISOTime(s:TBESENString):TBESENDate;
result:=double(pointer(@BESENDoubleNaN)^);
exit;
end;
result:=BESENMakeDay(StrToIntDef(copy(ss,1,4),0),StrToIntDef(copy(ss,5+(1*Offset),2),0),StrToIntDef(copy(ss,7+(2*Offset),2),0));
result:=BESENMakeDay(StrToIntDef(copy(ss,1,4),0),StrToIntDef(copy(ss,5+(Offset),2),0),StrToIntDef(copy(ss,7+(Offset+Offset),2),0));
end;
function ParseTime(const ss:TBESENString):TBESENDate;
var s,ms:TBESENString;
Expand Down Expand Up @@ -667,9 +667,10 @@ function BESENParseISOTime(s:TBESENString):TBESENDate;
exit;
end;
Hours:=StrToIntDef(copy(s,1,2),100);
Minutes:=StrToIntDef(copy(s,3+(1*Offset),2),100);
//Minutes:=StrToIntDef(copy(s,3+(1*Offset),2),100);
Minutes:=StrToIntDef(copy(s,3+(Offset),2),100);
if WithSeconds then begin
Seconds:=StrToIntDef(copy(s,5+(2*Offset),2),100);
Seconds:=StrToIntDef(copy(s,5+(Offset+Offset),2),100);
end else begin
Seconds:=0;
if length(ms)>0 then begin
Expand Down
6 changes: 6 additions & 0 deletions src/BESENDeclarativeEnvironmentRecord.pas
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,9 @@ constructor TBESENDeclarativeEnvironmentRecord.Create(AInstance:TObject);
FillChar(HashBuckets,sizeof(TBESENDeclarativeEnvironmentRecordHashBuckets),#0);
First:=nil;
Last:=nil;

HashSize:=256;

HashSizeMask:=HashSize-1;
HashedItems:=0;
HashBucketsUsed:=0;
Expand Down Expand Up @@ -155,7 +157,9 @@ procedure TBESENDeclarativeEnvironmentRecord.Clear;
First:=nil;
Last:=nil;
LastUsedItem:=nil;

HashSize:=256;

HashSizeMask:=HashSize-1;
HashedItems:=0;
HashBucketsUsed:=0;
Expand Down Expand Up @@ -215,7 +219,9 @@ procedure TBESENDeclarativeEnvironmentRecord.GrowAndRehashIfNeeded;
HashBucketsUsed:=0;
Item:=First;
while assigned(Item) do begin

Hash:=BESENHashKey(Item^.Key) and HashSizeMask;

Item^.Hash:=Hash;
if assigned(HashBuckets[Hash].HashLast) then begin
HashBuckets[Hash].HashLast^.HashNext:=Item;
Expand Down
5 changes: 5 additions & 0 deletions src/BESENHashMap.pas
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,9 @@ procedure TBESENHashMap.GrowAndRehashIfNeeded;

function TBESENHashMap.GetKey(const Key:TBESENString;Hash:TBESENHash=0):PBESENHashMapItem;
begin

if assigned(LastUsedItem) and (LastUsedItem^.Key=Key) then begin

result:=LastUsedItem;
Hash:=result^.Hash;
end else begin
Expand All @@ -185,9 +187,12 @@ function TBESENHashMap.GetKey(const Key:TBESENString;Hash:TBESENHash=0):PBESENHa
end;
Hash:=Hash and HashSizeMask;
result:=HashBuckets[Hash].HashFirst;

while assigned(result) and (result^.Key<>Key) do begin
result:=result^.HashNext;
end;


end;
if assigned(result) then begin
LastUsedItem:=result;
Expand Down
13 changes: 12 additions & 1 deletion src/BESENHashUtils.pas
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,24 @@

interface

uses BESENConstants,BESENTypes;
uses BESENConstants,BESENTypes
{$ifdef THRhash}
,thrHashUtils
{$endif}
;


function BESENHashKey(const Key:TBESENString):TBESENHash;
function BESENDoubleHash(Hash:TBESENHash):TBESENHash;

implementation

function BESENHashKey(const Key:TBESENString):TBESENHash;
{$ifdef THRhash}
begin
result:=thrHashKey(key);
end;
{$else}
{$ifdef PurePascal}
var i,h:longword;
begin
Expand Down Expand Up @@ -146,6 +156,7 @@ function BESENHashKey(const Key:TBESENString):TBESENHash;
{$endif}
{$endif}
{$endif}
{$endif}

function BESENDoubleHash(Hash:TBESENHash):TBESENHash;
begin
Expand Down
103 changes: 101 additions & 2 deletions src/BESENLexer.pas
Original file line number Diff line number Diff line change
Expand Up @@ -161,13 +161,18 @@ TBESENLexer=class(TBESENBaseObject)

implementation

uses {$ifdef BESENEmbarcaderoNextGen}System.Character,{$endif}BESEN,BESENRegExp,BESENErrors,BESENNumberUtils;
uses {$ifdef BESENEmbarcaderoNextGen}System.Character,{$endif}BESEN,BESENRegExp,BESENErrors,BESENNumberUtils
{$ifdef THRhash}
,thrHashUtils
{$endif}
;

type TKeywordToken=ltkBREAK..ltkYIELD;

TKeyword=TKeywordToken;

TKeywords=array of TKeyword;
TKeywordsHash=array of TBESENHash;

const KeywordNames:array[TKeywordToken] of TBESENUTF16STRING=
(// Used keywords
Expand All @@ -189,6 +194,10 @@ implementation

Keywords:TKeywords=nil;

{$ifdef THRhash2}
KeywordsHash:TKeywordsHash=nil;
{$endif}

constructor TBESENLexer.Create(AInstance:TObject);
begin
inherited Create(AInstance);
Expand Down Expand Up @@ -550,12 +559,61 @@ procedure TBESENLexer.GetToken(var AResult:TBESENLexerToken);

s:='';
end;


function FindKeyword(const Name:TBESENUTF16STRING):TBESENLexerTokenType;
var LowIndex,HighIndex,MiddleIndex:integer;
{$ifdef THRhash2}
aHash: TBESENHash;
aHash1: TBESENHash;
{$endif}
begin
result:=lttIDENTIFIER;
LowIndex:=0;
HighIndex:=length(Keywords)-1;

{$ifdef THRhash2}
aHash:=thrHashKey(Name);
while LowIndex<=HighIndex do begin
case (HighIndex-LowIndex)+1 of
1:begin
if KeywordsHash[
Keywords[LowIndex]
]=aHash then begin
result:=Keywords[LowIndex];
end;
end;
2:begin
if KeywordsHash[
Keywords[LowIndex]
]=aHash then begin
result:=Keywords[LowIndex];
end else if KeywordsHash[
Keywords[HighIndex]
]=aHash then begin
result:=Keywords[HighIndex];
end;
end;
else begin
MiddleIndex:=(LowIndex+HighIndex) div 2;

aHash1 :=KeywordsHash[ Keywords[MiddleIndex] ];

if aHash1=aHash then begin
result:=Keywords[MiddleIndex];
end else if LowIndex<>HighIndex then begin
if aHash1>aHash then begin
HighIndex:=MiddleIndex-1;
end else begin
LowIndex:=MiddleIndex+1;
end;
continue;
end;
end;
end;
break;
end;
{$else}
while LowIndex<=HighIndex do begin
case (HighIndex-LowIndex)+1 of
1:begin
Expand Down Expand Up @@ -586,6 +644,8 @@ procedure TBESENLexer.GetToken(var AResult:TBESENLexerToken);
end;
break;
end;

{$endif}
end;
begin
AResult.Name:='';
Expand Down Expand Up @@ -1370,13 +1430,47 @@ procedure InitKeywords;
var kt:TKeywordToken;
i:integer;
k:TKeyword;
sz:integer;
begin
SetLength(Keywords,(integer(high(TKeywordToken))-integer(low(TKeywordToken)))+1);
sz:=(integer(high(TKeywordToken))-integer(low(TKeywordToken)))+1;

SetLength(Keywords,sz);

{$ifdef THRhash2}
//tigra: add hash calc of keys
SetLength(KeywordsHash,sz);
{$endif}

i:=0;
for kt:=low(TKeywordToken) to high(TKeywordToken) do begin
Keywords[i]:=kt;

{$ifdef THRhash2}
//tigra: calc hash and store
KeywordsHash[i]:=thrHashKey(KeywordNames[kt]);
{$endif}
inc(i);
end;

//sort keywords by keywordNames

{$ifdef THRhash2}
i:=0;
while (i+1)<length(Keywords) do begin
if KeywordsHash[Keywords[i]]>KeywordsHash[Keywords[i+1]] then begin
k:=Keywords[i];
Keywords[i]:=Keywords[i+1];
Keywords[i+1]:=k;
if i>0 then begin
dec(i);
end else begin
inc(i);
end;
end else begin
inc(i);
end;
end;
{$else}
i:=0;
while (i+1)<length(Keywords) do begin
if KeywordNames[Keywords[i]]>KeywordNames[Keywords[i+1]] then begin
Expand All @@ -1392,11 +1486,16 @@ procedure InitKeywords;
inc(i);
end;
end;
{$endif}

end;

procedure DoneKeywords;
begin
SetLength(Keywords,0);
{$ifdef THRhash2}
SetLength(KeywordsHash,0);
{$endif}
end;

procedure InitBESEN;
Expand Down
4 changes: 4 additions & 0 deletions src/BESENObject.pas
Original file line number Diff line number Diff line change
Expand Up @@ -496,7 +496,9 @@ constructor TBESENObjectPropertyContainer.Create(AInstance:TObject;ASorted:boole
Last:=nil;
EnumeratorFirst:=nil;
EnumeratorLast:=nil;

HashSize:=256;

HashSizeMask:=HashSize-1;
HashedItems:=0;
HashBucketsUsed:=0;
Expand Down Expand Up @@ -544,7 +546,9 @@ procedure TBESENObjectPropertyContainer.Clear;
end;
First:=nil;
Last:=nil;

HashSize:=256;

HashSizeMask:=HashSize-1;
HashedItems:=0;
HashBucketsUsed:=0;
Expand Down
6 changes: 5 additions & 1 deletion src/BESENParser.pas
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,9 @@ function TBESENParser.Parse(IsFunction,IsJSON:boolean):TBESENASTNode;
OldToken:=CurrentToken;
NextToken;
if NextIsSemicolon then begin
if (length(OldToken.StringValue)=10) and (copy(Lexer.Source,OldToken.OldPosition,10)='use strict') then begin
if (length(OldToken.StringValue)=10) then begin

if (copy(Lexer.Source,OldToken.OldPosition,10)='use strict') then begin
if UseStrictAlreadyParsed then begin
AddWarning('"use strict"/''use strict'' already seen!');
end else begin
Expand All @@ -311,6 +313,8 @@ function TBESENParser.Parse(IsFunction,IsJSON:boolean):TBESENASTNode;
end;
end;
end;

end;
FirstDirective:=false;
end else begin
IsDirectivePrologue:=false;
Expand Down
Loading