mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2026-02-04 04:14:48 +01:00
* Initial check-in
git-svn-id: trunk@14859 -
This commit is contained in:
parent
82f0d61ad9
commit
59bd32b7ea
15
.gitattributes
vendored
15
.gitattributes
vendored
@ -1980,6 +1980,21 @@ packages/fcl-image/src/pngcomn.pp svneol=native#text/plain
|
||||
packages/fcl-image/src/pscanvas.pp svneol=native#text/plain
|
||||
packages/fcl-image/src/targacmn.pp svneol=native#text/plain
|
||||
packages/fcl-image/src/xwdfile.pp svneol=native#text/plain
|
||||
packages/fcl-js/Makefile svneol=native#text/plain
|
||||
packages/fcl-js/Makefile.fpc svneol=native#text/plain
|
||||
packages/fcl-js/README.TXT svneol=native#text/plain
|
||||
packages/fcl-js/fpmake.pp svneol=native#text/plain
|
||||
packages/fcl-js/src/jsbase.pp svneol=native#text/plain
|
||||
packages/fcl-js/src/jsparser.pp svneol=native#text/plain
|
||||
packages/fcl-js/src/jsscanner.pp svneol=native#text/plain
|
||||
packages/fcl-js/src/jstree.pp svneol=native#text/plain
|
||||
packages/fcl-js/tests/tcparser.pp svneol=native#text/plain
|
||||
packages/fcl-js/tests/tcscanner.pp svneol=native#text/plain
|
||||
packages/fcl-js/tests/testjs.ico -text
|
||||
packages/fcl-js/tests/testjs.lpi svneol=native#text/plain
|
||||
packages/fcl-js/tests/testjs.lpr svneol=native#text/plain
|
||||
packages/fcl-js/tests/testjs.manifest svneol=native#text/plain
|
||||
packages/fcl-js/tests/testjs.rc svneol=native#text/plain
|
||||
packages/fcl-json/Makefile svneol=native#text/plain
|
||||
packages/fcl-json/Makefile.fpc svneol=native#text/plain
|
||||
packages/fcl-json/examples/confdemo.lpi svneol=native#text/plain
|
||||
|
||||
2354
packages/fcl-js/Makefile
Normal file
2354
packages/fcl-js/Makefile
Normal file
File diff suppressed because it is too large
Load Diff
26
packages/fcl-js/Makefile.fpc
Normal file
26
packages/fcl-js/Makefile.fpc
Normal file
@ -0,0 +1,26 @@
|
||||
#
|
||||
# Makefile.fpc for Javascript Parser
|
||||
#
|
||||
|
||||
[package]
|
||||
name=fcl-js
|
||||
version=2.5.1
|
||||
|
||||
[target]
|
||||
units=jsbase jstree jsscanner jsparser
|
||||
|
||||
[install]
|
||||
fpcpackage=y
|
||||
|
||||
[default]
|
||||
fpcdir=../..
|
||||
|
||||
[compiler]
|
||||
includedir=src
|
||||
sourcedir=src
|
||||
|
||||
[shared]
|
||||
build=n
|
||||
|
||||
[rules]
|
||||
.NOTPARALLEL:
|
||||
23
packages/fcl-js/README.TXT
Normal file
23
packages/fcl-js/README.TXT
Normal file
@ -0,0 +1,23 @@
|
||||
This is a package that contains a Javascript Scanner/parser/Syntax tree.
|
||||
|
||||
The following units are defined:
|
||||
|
||||
jsbase: the definition of Javascript values. Used to represent constant values.
|
||||
jstree: The Javascript syntax tree elements. Used in the parser to describe a source program
|
||||
jsscanner: the Javascript scanner. Currently not yet unicode-enabled.
|
||||
jsparser: the Javascript parser. Builds a complete javascript syntax tree.
|
||||
|
||||
The tests directory contains a set of FPCUnit tests to test the scanner and parser.
|
||||
It needs Lazarus to run.
|
||||
|
||||
Todo:
|
||||
- Add more tests.
|
||||
- Unicode support.
|
||||
- Runtime-engine ?
|
||||
|
||||
The idea for the tree elements and the parser come from the Libsee library,
|
||||
written by David Leonard.
|
||||
|
||||
Enjoy!
|
||||
|
||||
Michael.
|
||||
37
packages/fcl-js/fpmake.pp
Normal file
37
packages/fcl-js/fpmake.pp
Normal file
@ -0,0 +1,37 @@
|
||||
{$ifndef ALLPACKAGES}
|
||||
{$mode objfpc}{$H+}
|
||||
program fpmake;
|
||||
|
||||
uses fpmkunit;
|
||||
|
||||
Var
|
||||
P : TPackage;
|
||||
T : TTarget;
|
||||
begin
|
||||
With Installer do
|
||||
begin
|
||||
{$endif ALLPACKAGES}
|
||||
|
||||
P:=AddPackage('fcl-js');
|
||||
{$ifdef ALLPACKAGES}
|
||||
P.Directory:='fcl-js';
|
||||
{$endif ALLPACKAGES}
|
||||
P.Version:='1.0';
|
||||
P.Author := 'Michael Van Canneyt';
|
||||
P.License := 'LGPL with FPC modification';
|
||||
P.HomepageURL := 'www.freepascal.org';
|
||||
P.Email := 'michael@freepascal.org';
|
||||
P.Description := 'Javascript scanner/parser/syntax tree units';
|
||||
|
||||
P.SourcePath.Add('src');
|
||||
P.IncludePath.Add('src');
|
||||
|
||||
T:=P.Targets.AddUnit('jsbase.pp');
|
||||
T:=P.Targets.AddUnit('jstree.pp');
|
||||
T:=P.Targets.AddUnit('jsscanner.pp');
|
||||
T:=P.Targets.AddUnit('jsparser.pp');
|
||||
{$ifndef ALLPACKAGES}
|
||||
Run;
|
||||
end;
|
||||
end.
|
||||
{$endif ALLPACKAGES}
|
||||
175
packages/fcl-js/src/jsbase.pp
Normal file
175
packages/fcl-js/src/jsbase.pp
Normal file
@ -0,0 +1,175 @@
|
||||
unit jsbase;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils;
|
||||
|
||||
Type
|
||||
TJSType = (jstUNDEFINED,jstNull,jstBoolean,jstNumber,jstString,jstObject,jstReference,JSTCompletion);
|
||||
|
||||
TJSString = WideString;
|
||||
TJSNumber = Double;
|
||||
|
||||
{ TJSValue }
|
||||
|
||||
TJSValue = Class(TObject)
|
||||
private
|
||||
FValueType: TJSType;
|
||||
FValue : Record
|
||||
Case Integer of
|
||||
0 : (P : Pointer);
|
||||
1 : (F : TJSNumber);
|
||||
2 : (I : Integer);
|
||||
end;
|
||||
procedure ClearValue(ANewValue: TJSType);
|
||||
function GetAsBoolean: Boolean;
|
||||
function GetAsCompletion: TObject;
|
||||
function GetAsNumber: TJSNumber;
|
||||
function GetAsObject: TObject;
|
||||
function GetAsReference: TObject;
|
||||
function GetAsString: TJSString;
|
||||
function GetIsNull: Boolean;
|
||||
function GetIsUndefined: Boolean;
|
||||
procedure SetAsBoolean(const AValue: Boolean);
|
||||
procedure SetAsCompletion(const AValue: TObject);
|
||||
procedure SetAsNumber(const AValue: TJSNumber);
|
||||
procedure SetAsObject(const AValue: TObject);
|
||||
procedure SetAsReference(const AValue: TObject);
|
||||
procedure SetAsString(const AValue: TJSString);
|
||||
procedure SetIsNull(const AValue: Boolean);
|
||||
procedure SetIsUndefined(const AValue: Boolean);
|
||||
Public
|
||||
Destructor Destroy; override;
|
||||
Property ValueType : TJSType Read FValueType;
|
||||
Property IsUndefined : Boolean Read GetIsUndefined Write SetIsUndefined;
|
||||
Property IsNull : Boolean Read GetIsNull Write SetIsNull;
|
||||
Property AsNumber : TJSNumber Read GetAsNumber Write SetAsNumber;
|
||||
Property AsBoolean : Boolean Read GetAsBoolean Write SetAsBoolean;
|
||||
Property AsObject : TObject Read GetAsObject Write SetAsObject;
|
||||
Property AsString : TJSString Read GetAsString Write SetAsString;
|
||||
Property AsReference : TObject Read GetAsReference Write SetAsReference;
|
||||
Property AsCompletion : TObject Read GetAsCompletion Write SetAsCompletion;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
{ TJSValue }
|
||||
|
||||
|
||||
function TJSValue.GetAsBoolean: Boolean;
|
||||
begin
|
||||
If (ValueType=jstBoolean) then
|
||||
Result:=(FValue.I<>0)
|
||||
else
|
||||
Result:=False;
|
||||
end;
|
||||
|
||||
function TJSValue.GetAsCompletion: TObject;
|
||||
begin
|
||||
Result:=TObject(FValue.P);
|
||||
end;
|
||||
|
||||
function TJSValue.GetAsNumber: TJSNumber;
|
||||
begin
|
||||
If (ValueType=jstNumber) then
|
||||
Result:=FValue.F;
|
||||
end;
|
||||
|
||||
function TJSValue.GetAsObject: TObject;
|
||||
begin
|
||||
If (ValueType=jstObject) then
|
||||
Result:=TObject(FValue.P);
|
||||
end;
|
||||
|
||||
function TJSValue.GetAsReference: TObject;
|
||||
begin
|
||||
If (ValueType=jstReference) then
|
||||
Result:=TObject(FValue.P);
|
||||
end;
|
||||
|
||||
function TJSValue.GetAsString: TJSString;
|
||||
begin
|
||||
If (ValueType=jstString) then
|
||||
Result:=String(FValue.P);
|
||||
end;
|
||||
|
||||
function TJSValue.GetIsNull: Boolean;
|
||||
begin
|
||||
Result:=(ValueType=jstNull);
|
||||
end;
|
||||
|
||||
function TJSValue.GetIsUndefined: Boolean;
|
||||
begin
|
||||
Result:=(fValueType=jstUndefined);
|
||||
end;
|
||||
|
||||
procedure TJSValue.ClearValue(ANewValue : TJSType);
|
||||
|
||||
begin
|
||||
Case FValueType of
|
||||
jstString : String(FValue.P):='';
|
||||
jstNumber : FValue.F:=0;
|
||||
else
|
||||
FValue.I:=0;
|
||||
end;
|
||||
FValueType:=ANewValue;
|
||||
end;
|
||||
|
||||
procedure TJSValue.SetAsBoolean(const AValue: Boolean);
|
||||
begin
|
||||
ClearValue(jstBoolean);
|
||||
FValue.I:=Ord(AValue);
|
||||
end;
|
||||
|
||||
procedure TJSValue.SetAsCompletion(const AValue: TObject);
|
||||
begin
|
||||
ClearValue(jstBoolean);
|
||||
FValue.P:=AValue;
|
||||
end;
|
||||
|
||||
procedure TJSValue.SetAsNumber(const AValue: TJSNumber);
|
||||
begin
|
||||
ClearValue(jstNumber);
|
||||
FValue.F:=AValue;
|
||||
end;
|
||||
|
||||
procedure TJSValue.SetAsObject(const AValue: TObject);
|
||||
begin
|
||||
ClearValue(jstObject);
|
||||
FValue.P:=AVAlue;
|
||||
end;
|
||||
|
||||
procedure TJSValue.SetAsReference(const AValue: TObject);
|
||||
begin
|
||||
ClearValue(jstReference);
|
||||
FValue.P:=AVAlue;
|
||||
end;
|
||||
|
||||
procedure TJSValue.SetAsString(const AValue: TJSString);
|
||||
begin
|
||||
ClearValue(jstString);
|
||||
String(FValue.P):=AValue;
|
||||
end;
|
||||
|
||||
procedure TJSValue.SetIsNull(const AValue: Boolean);
|
||||
begin
|
||||
ClearValue(jstNull);
|
||||
end;
|
||||
|
||||
procedure TJSValue.SetIsUndefined(const AValue: Boolean);
|
||||
begin
|
||||
ClearValue(jstUndefined);
|
||||
end;
|
||||
|
||||
destructor TJSValue.Destroy;
|
||||
begin
|
||||
ClearValue(jstUndefined);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
|
||||
end.
|
||||
|
||||
2100
packages/fcl-js/src/jsparser.pp
Normal file
2100
packages/fcl-js/src/jsparser.pp
Normal file
File diff suppressed because it is too large
Load Diff
909
packages/fcl-js/src/jsscanner.pp
Normal file
909
packages/fcl-js/src/jsscanner.pp
Normal file
@ -0,0 +1,909 @@
|
||||
{
|
||||
This file is part of the Free Component Library
|
||||
|
||||
ECMAScript (JavaScript) source lexical scanner
|
||||
|
||||
See the file COPYING.FPC, included in this distribution,
|
||||
for details about the copyright.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
**********************************************************************}
|
||||
|
||||
{$mode objfpc}
|
||||
{$h+}
|
||||
|
||||
unit JSScanner;
|
||||
|
||||
interface
|
||||
|
||||
uses SysUtils, Classes;
|
||||
|
||||
resourcestring
|
||||
SErrInvalidCharacter = 'Invalid character ''%s''';
|
||||
SErrOpenString = 'string exceeds end of line';
|
||||
SErrIncludeFileNotFound = 'Could not find include file ''%s''';
|
||||
SErrIfXXXNestingLimitReached = 'Nesting of $IFxxx too deep';
|
||||
SErrInvalidPPElse = '$ELSE without matching $IFxxx';
|
||||
SErrInvalidPPEndif = '$ENDIF without matching $IFxxx';
|
||||
SInvalidHexadecimalNumber = 'Invalid decimal number';
|
||||
SErrInvalidNonEqual = 'SyntaxError: != or !== expected';
|
||||
|
||||
type
|
||||
|
||||
TJSToken = (tjsUnknown,
|
||||
// Specials
|
||||
tjsEOF,tjsWhiteSpace,tjsChar,tjsString, tjsIdentifier,tjsNumber, tjsComment,tjsREGEX, tjsRESERVED,
|
||||
tjsANDAND, tjsANDEQ,
|
||||
tjsBraceOpen,tjsBraceClose,tjsSQuaredBraceOpen,tjsSQuaredBraceClose,tjsCurlyBraceOpen,tjsCurlyBraceClose,
|
||||
tjsCOMMA,tjsCOLON, tjsDOT,tjsSEMICOLON, tjsASSIGN,tjsGT,tjsLT, tjsConditional,
|
||||
tjsPLUS,tjsMINUS,tjsMUL,tjsDIV,tjsAnd,tjsOR, tjsInv, tjsMod, tjsXOR, tjsNot,
|
||||
tjsEQ,
|
||||
tjsGE,
|
||||
tjsLE, tjsLSHIFT, tjsLSHIFTEQ,
|
||||
tjsMINUSEQ, tjsMINUSMINUS, tjsMODEQ,tjsDIVEQ,tjsXOREq,
|
||||
tjsNE,
|
||||
tjsOREQ, tjsOROR,
|
||||
tjsPLUSEQ, tjsPLUSPLUS,
|
||||
tjsURSHIFT, tjsURSHIFTEQ,
|
||||
tjsRSHIFT, tjsRSHIFTEQ,
|
||||
tjsSEQ, tjsSNE, tjsMULEQ,
|
||||
{ Reserved words start here. They must be last }
|
||||
tjsBREAK,tjsCASE, tjsCATCH, tjsCONTINUE,
|
||||
tjsDEFAULT, tjsDELETE, tjsDO,
|
||||
tjsELSE,
|
||||
tjsFalse, tjsFINALLY, tjsFOR, tjsFUNCTION,
|
||||
tjsIF, tjsIN, tjsINSTANCEOF,
|
||||
tjsNEW,tjsNULL,
|
||||
tjsRETURN,
|
||||
tjsSWITCH,
|
||||
tjsTHIS, tjsTHROW, tjsTrue, tjsTRY, tjsTYPEOF,
|
||||
tjsVAR, tjsVOID,
|
||||
tjsWHILE, tjsWITH
|
||||
);
|
||||
|
||||
const
|
||||
FirstKeyword = tjsBreak;
|
||||
LastKeyWord = tJSWith;
|
||||
|
||||
TokenInfos: array[TJSToken] of string = ('unknown',
|
||||
// Specials
|
||||
'EOF','whitespace','Char','String', 'identifier','number','comment','regular expression', 'reserved word',
|
||||
'&&','&=',
|
||||
'(',')','[',']','{','}',
|
||||
',',':','.',';','=','>','<','?',
|
||||
'+','-','*','/','&','|','~','%','^','!',
|
||||
'==',
|
||||
'>=',
|
||||
'<=', '<<', '<<=',
|
||||
'-=', '--', '%=', '/=','^=',
|
||||
'!=',
|
||||
'|=', '||',
|
||||
'+=', '++',
|
||||
'>>>', '>>>=',
|
||||
'>>', '>>=',
|
||||
'===', '!==', '*=',
|
||||
// Identifiers last
|
||||
'break','case','catch', 'continue',
|
||||
'default','delete', 'do',
|
||||
'else',
|
||||
'false','finally', 'for', 'function',
|
||||
'if', 'in', 'instanceof',
|
||||
'new','null',
|
||||
'return',
|
||||
'switch',
|
||||
'this', 'throw', 'true', 'try', 'typeof',
|
||||
'var', 'void',
|
||||
'while', 'with'
|
||||
);
|
||||
|
||||
Type
|
||||
TLineReader = class
|
||||
public
|
||||
function IsEOF: Boolean; virtual; abstract;
|
||||
function ReadLine: string; virtual; abstract;
|
||||
end;
|
||||
|
||||
{ TStreamLineReader }
|
||||
|
||||
TStreamLineReader = class(TLineReader)
|
||||
private
|
||||
FStream : TStream;
|
||||
Buffer : Array[0..1024] of Byte;
|
||||
FBufPos,
|
||||
FBufLen : Integer;
|
||||
procedure FillBuffer;
|
||||
public
|
||||
Constructor Create(AStream : TStream);
|
||||
function IsEOF: Boolean; override;
|
||||
function ReadLine: string; override;
|
||||
end;
|
||||
|
||||
TFileLineReader = class(TLineReader)
|
||||
private
|
||||
FTextFile: Text;
|
||||
FileOpened: Boolean;
|
||||
public
|
||||
constructor Create(const AFilename: string);
|
||||
destructor Destroy; override;
|
||||
function IsEOF: Boolean; override;
|
||||
function ReadLine: string; override;
|
||||
end;
|
||||
|
||||
EJSScannerError = class(Exception);
|
||||
|
||||
{ TJSScanner }
|
||||
|
||||
TJSScanner = class
|
||||
private
|
||||
FReturnComments: Boolean;
|
||||
FReturnWhiteSpace: Boolean;
|
||||
FSourceFile: TLineReader;
|
||||
FSourceFilename: string;
|
||||
FCurRow: Integer;
|
||||
FCurToken: TJSToken;
|
||||
FCurTokenString: string;
|
||||
FCurLine: string;
|
||||
FDefines: TStrings;
|
||||
TokenStr: PChar;
|
||||
FSourceStream : TStream;
|
||||
FOwnSourceFile : Boolean;
|
||||
function CommentDiv: TJSToken;
|
||||
function DoIdentifier : TJSToken;
|
||||
function DoMultiLineComment: TJSToken;
|
||||
function DoNumericLiteral: TJSToken;
|
||||
function DoSingleLineComment: TJSToken;
|
||||
function DoStringLiteral: TJSToken;
|
||||
function DoWhiteSpace: TJSToken;
|
||||
function FetchLine: Boolean;
|
||||
function GetCurColumn: Integer;
|
||||
function ReadUnicodeEscape: WideChar;
|
||||
protected
|
||||
procedure Error(const Msg: string);overload;
|
||||
procedure Error(const Msg: string; Args: array of Const);overload;
|
||||
public
|
||||
constructor Create(ALineReader: TLineReader);
|
||||
constructor Create(AStream : TStream);
|
||||
destructor Destroy; override;
|
||||
procedure OpenFile(const AFilename: string);
|
||||
Function FetchToken: TJSToken;
|
||||
Function IsEndOfLine : Boolean;
|
||||
Property ReturnComments : Boolean Read FReturnComments Write FReturnComments;
|
||||
Property ReturnWhiteSpace : Boolean Read FReturnWhiteSpace Write FReturnWhiteSpace;
|
||||
property SourceFile: TLineReader read FSourceFile;
|
||||
property CurFilename: string read FSourceFilename;
|
||||
property CurLine: string read FCurLine;
|
||||
property CurRow: Integer read FCurRow;
|
||||
property CurColumn: Integer read GetCurColumn;
|
||||
property CurToken: TJSToken read FCurToken;
|
||||
property CurTokenString: string read FCurTokenString;
|
||||
end;
|
||||
|
||||
|
||||
implementation
|
||||
|
||||
|
||||
constructor TFileLineReader.Create(const AFilename: string);
|
||||
begin
|
||||
inherited Create;
|
||||
Assign(FTextFile, AFilename);
|
||||
Reset(FTextFile);
|
||||
FileOpened := true;
|
||||
end;
|
||||
|
||||
destructor TFileLineReader.Destroy;
|
||||
begin
|
||||
if FileOpened then
|
||||
Close(FTextFile);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
function TFileLineReader.IsEOF: Boolean;
|
||||
begin
|
||||
Result := EOF(FTextFile);
|
||||
end;
|
||||
|
||||
function TFileLineReader.ReadLine: string;
|
||||
begin
|
||||
ReadLn(FTextFile, Result);
|
||||
end;
|
||||
|
||||
constructor TJSScanner.Create(ALineReader: TLineReader);
|
||||
begin
|
||||
inherited Create;
|
||||
FSourceFile := ALineReader;
|
||||
end;
|
||||
|
||||
constructor TJSScanner.Create(AStream: TStream);
|
||||
begin
|
||||
FSourceStream:=ASTream;
|
||||
FOwnSourceFile:=True;
|
||||
Create(TStreamLineReader.Create(AStream));
|
||||
end;
|
||||
|
||||
destructor TJSScanner.Destroy;
|
||||
begin
|
||||
If FOwnSourceFile then
|
||||
FSourceFile.Free;
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
procedure TJSScanner.OpenFile(const AFilename: string);
|
||||
begin
|
||||
FSourceFile := TFileLineReader.Create(AFilename);
|
||||
FSourceFilename := AFilename;
|
||||
end;
|
||||
|
||||
|
||||
procedure TJSScanner.Error(const Msg: string);
|
||||
begin
|
||||
raise EJSScannerError.Create(Msg);
|
||||
end;
|
||||
|
||||
procedure TJSScanner.Error(const Msg: string; Args: array of Const);
|
||||
begin
|
||||
raise EJSScannerError.CreateFmt(Msg, Args);
|
||||
end;
|
||||
|
||||
function TJSScanner.FetchLine: Boolean;
|
||||
begin
|
||||
if FSourceFile.IsEOF then
|
||||
begin
|
||||
FCurLine := '';
|
||||
TokenStr := nil;
|
||||
Result := false;
|
||||
end else
|
||||
begin
|
||||
FCurLine := FSourceFile.ReadLine;
|
||||
TokenStr := PChar(CurLine);
|
||||
Result := true;
|
||||
Inc(FCurRow);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TJSScanner.DoWhiteSpace : TJSToken;
|
||||
|
||||
begin
|
||||
Result:=tjsWhitespace;
|
||||
repeat
|
||||
Inc(TokenStr);
|
||||
if TokenStr[0] = #0 then
|
||||
if not FetchLine then
|
||||
begin
|
||||
FCurToken := Result;
|
||||
exit;
|
||||
end;
|
||||
until not (TokenStr[0] in [#9, ' ']);
|
||||
end;
|
||||
|
||||
function TJSScanner.DoSingleLineComment : TJSToken;
|
||||
|
||||
Var
|
||||
TokenStart : PChar;
|
||||
Len : Integer;
|
||||
|
||||
begin
|
||||
Inc(TokenStr);
|
||||
TokenStart := TokenStr;
|
||||
while TokenStr[0] <> #0 do
|
||||
Inc(TokenStr);
|
||||
Len:=TokenStr-TokenStart;
|
||||
SetLength(FCurTokenString, Len);
|
||||
if (Len>0) then
|
||||
Move(TokenStart^,FCurTokenString[1],Len);
|
||||
Result := tjsComment;
|
||||
end;
|
||||
|
||||
function TJSScanner.DoMultiLineComment : TJSToken;
|
||||
|
||||
Var
|
||||
TokenStart : PChar;
|
||||
Len,OLen : Integer;
|
||||
PrevToken : Char;
|
||||
|
||||
begin
|
||||
Inc(TokenStr);
|
||||
TokenStart := TokenStr;
|
||||
FCurTokenString := '';
|
||||
OLen:= 0;
|
||||
PrevToken:=#0;
|
||||
while Not ((TokenStr[0]='/') and (PrevToken='*')) do
|
||||
begin
|
||||
if (TokenStr[0]=#0) then
|
||||
begin
|
||||
Len:=TokenStr-TokenStart+1;
|
||||
SetLength(FCurTokenString,OLen+Len);
|
||||
if Len>1 then
|
||||
Move(TokenStart^,FCurTokenString[OLen+1],Len-1);
|
||||
Inc(OLen,Len);
|
||||
FCurTokenString[OLen]:=#10;
|
||||
if not FetchLine then
|
||||
begin
|
||||
Result := tjsEOF;
|
||||
FCurToken := Result;
|
||||
exit;
|
||||
end;
|
||||
TokenStart := TokenStr;
|
||||
PrevToken:=#0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
PrevToken:=TokenStr[0];
|
||||
Inc(TokenStr);
|
||||
end;
|
||||
end;
|
||||
Len:=TokenStr-TokenStart-1; // -1 for *
|
||||
SetLength(FCurTokenString, Olen+Len);
|
||||
if (Len>0) then
|
||||
Move(TokenStart^, FCurTokenString[Olen + 1], Len);
|
||||
Inc(TokenStr);
|
||||
Result := tjsComment;
|
||||
end;
|
||||
|
||||
function TJSScanner.CommentDiv : TJSToken;
|
||||
|
||||
begin
|
||||
FCurTokenString := '';
|
||||
Inc(TokenStr);
|
||||
if (TokenStr[0] = '/') then // Single-line comment
|
||||
Result:=DoSingleLineComment
|
||||
else if (TokenStr[0]='*') then
|
||||
Result:=DoMultiLineComment
|
||||
else if (TokenStr[0] = '=') then // Single-line comment
|
||||
begin
|
||||
Result:=tjsDiveQ;
|
||||
Inc(TokenStr)
|
||||
end
|
||||
else
|
||||
Result:=tjsDiv;
|
||||
end;
|
||||
|
||||
Function TJSScanner.ReadUnicodeEscape : WideChar;
|
||||
|
||||
Var
|
||||
S : String;
|
||||
I : Integer;
|
||||
|
||||
begin
|
||||
S:='0000';
|
||||
For I:=1 to 4 do
|
||||
begin
|
||||
Inc(TokenStr);
|
||||
Case TokenStr[0] of
|
||||
'0'..'9','A'..'F','a'..'f' :
|
||||
S[i]:=Upcase(TokenStr[0]);
|
||||
else
|
||||
Error(SErrInvalidCharacter, [TokenStr[0]]);
|
||||
end;
|
||||
end;
|
||||
// Takes care of conversion... This needs improvement !!
|
||||
Result:=WideChar(StrToInt('$'+S));
|
||||
end;
|
||||
|
||||
Function TJSScanner.DoStringLiteral : TJSToken;
|
||||
|
||||
Var
|
||||
Delim : Char;
|
||||
TokenStart : PChar;
|
||||
Len,OLen,I : Integer;
|
||||
S : String;
|
||||
|
||||
begin
|
||||
Delim:=TokenStr[0];
|
||||
Inc(TokenStr);
|
||||
TokenStart := TokenStr;
|
||||
OLen := 0;
|
||||
FCurTokenString := '';
|
||||
while not (TokenStr[0] in [#0,Delim]) do
|
||||
begin
|
||||
if (TokenStr[0]='\') then
|
||||
begin
|
||||
// Save length
|
||||
Len := TokenStr - TokenStart;
|
||||
Inc(TokenStr);
|
||||
// Read escaped token
|
||||
Case TokenStr[0] of
|
||||
'"' : S:='"';
|
||||
't' : S:=#9;
|
||||
'b' : S:=#8;
|
||||
'n' : S:=#10;
|
||||
'r' : S:=#13;
|
||||
'f' : S:=#12;
|
||||
'\' : S:='\';
|
||||
'/' : S:='/';
|
||||
'u' : begin
|
||||
S:=ReadUniCodeEscape;
|
||||
end;
|
||||
#0 : Error(SErrOpenString);
|
||||
else
|
||||
Error(SErrInvalidCharacter, [TokenStr[0]]);
|
||||
end;
|
||||
SetLength(FCurTokenString, OLen + Len+1+Length(S));
|
||||
if Len > 0 then
|
||||
Move(TokenStart^, FCurTokenString[OLen + 1], Len);
|
||||
Move(S[1],FCurTokenString[OLen + Len+1],Length(S));
|
||||
Inc(OLen, Len+Length(S));
|
||||
// Next char
|
||||
// Inc(TokenStr);
|
||||
TokenStart := TokenStr+1;
|
||||
end;
|
||||
if TokenStr[0] = #0 then
|
||||
Error(SErrOpenString);
|
||||
Inc(TokenStr);
|
||||
end;
|
||||
if TokenStr[0] = #0 then
|
||||
Error(SErrOpenString);
|
||||
Len := TokenStr - TokenStart;
|
||||
SetLength(FCurTokenString, OLen + Len);
|
||||
if Len > 0 then
|
||||
Move(TokenStart^, FCurTokenString[OLen+1], Len);
|
||||
Inc(TokenStr);
|
||||
Result := tjsString;
|
||||
end;
|
||||
|
||||
function TJSScanner.DoNumericLiteral :TJSToken;
|
||||
|
||||
Var
|
||||
TokenStart : PChar;
|
||||
Len : Integer;
|
||||
|
||||
begin
|
||||
TokenStart := TokenStr;
|
||||
while true do
|
||||
begin
|
||||
Inc(TokenStr);
|
||||
case TokenStr[0] of
|
||||
'x':
|
||||
If (TokenStart[0]='0') and ((TokenStr-TokenStart)=1) then
|
||||
begin
|
||||
Inc(TokenStr);
|
||||
while Upcase(TokenStr[0]) in ['0'..'9','A'..'F'] do
|
||||
Inc(TokenStr);
|
||||
end
|
||||
else
|
||||
Error(SInvalidHexadecimalNumber);
|
||||
'.':
|
||||
begin
|
||||
if TokenStr[1] in ['0'..'9', 'e', 'E'] then
|
||||
begin
|
||||
Inc(TokenStr);
|
||||
repeat
|
||||
Inc(TokenStr);
|
||||
until not (TokenStr[0] in ['0'..'9', 'e', 'E','-','+']);
|
||||
end;
|
||||
break;
|
||||
end;
|
||||
'0'..'9': ;
|
||||
'e', 'E':
|
||||
begin
|
||||
Inc(TokenStr);
|
||||
if TokenStr[0] in ['-','+'] then
|
||||
Inc(TokenStr);
|
||||
while TokenStr[0] in ['0'..'9'] do
|
||||
Inc(TokenStr);
|
||||
break;
|
||||
end;
|
||||
else
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
Len:=TokenStr-TokenStart;
|
||||
Setlength(FCurTokenString, Len);
|
||||
if (Len>0) then
|
||||
Move(TokenStart^,FCurTokenString[1],Len);
|
||||
Result := tjsNumber;
|
||||
end;
|
||||
|
||||
function TJSScanner.DoIdentifier : TJSToken;
|
||||
|
||||
Var
|
||||
TokenStart:PChar;
|
||||
Len : Integer;
|
||||
I : TJSToken;
|
||||
|
||||
begin
|
||||
Result:=tjsIdentifier;
|
||||
TokenStart := TokenStr;
|
||||
repeat
|
||||
Inc(TokenStr);
|
||||
If (TokenStr[0]='\') and (TokenStr[1]='u') then
|
||||
until not (TokenStr[0] in ['A'..'Z', 'a'..'z', '0'..'9', '_','$']);
|
||||
Len:=(TokenStr-TokenStart);
|
||||
SetLength(FCurTokenString,Len);
|
||||
if Len > 0 then
|
||||
Move(TokenStart^,FCurTokenString[1],Len);
|
||||
// Check if this is a keyword or identifier
|
||||
// !!!: Optimize this!
|
||||
I:=FirstKeyword;
|
||||
While (Result=tjsIdentifier) and (I<=Lastkeyword) do
|
||||
begin
|
||||
if (CurTokenString=TokenInfos[i]) then
|
||||
begin
|
||||
Result := i;
|
||||
FCurToken := Result;
|
||||
exit;
|
||||
end;
|
||||
I:=Succ(I);
|
||||
end
|
||||
end;
|
||||
|
||||
function TJSScanner.FetchToken: TJSToken;
|
||||
|
||||
|
||||
var
|
||||
TokenStart, CurPos: PChar;
|
||||
i: TJSToken;
|
||||
OldLength, SectionLength, NestingLevel, Index: Integer;
|
||||
|
||||
begin
|
||||
|
||||
Repeat
|
||||
if TokenStr = nil then
|
||||
if not FetchLine then
|
||||
begin
|
||||
Result := tjsEOF;
|
||||
FCurToken := Result;
|
||||
exit;
|
||||
end;
|
||||
CurPos:=TokenStr;
|
||||
FCurTokenString := '';
|
||||
case TokenStr[0] of
|
||||
#0: // Empty line
|
||||
begin
|
||||
FetchLine;
|
||||
Result := tjsWhitespace;
|
||||
end;
|
||||
'/' :
|
||||
Result:=CommentDiv;
|
||||
#9, ' ':
|
||||
Result := DoWhiteSpace;
|
||||
'''','"':
|
||||
Result:=DoStringLiteral;
|
||||
'0'..'9':
|
||||
Result:=DoNumericLiteral;
|
||||
'&':
|
||||
begin
|
||||
Inc(TokenStr);
|
||||
If Tokenstr[0]='&' then
|
||||
begin
|
||||
Inc(TokenStr);
|
||||
Result := tjsAndAnd;
|
||||
end
|
||||
else If Tokenstr[0]='=' then
|
||||
begin
|
||||
Inc(TokenStr);
|
||||
Result := tjsAndEQ;
|
||||
end
|
||||
else
|
||||
Result := tjsAnd;
|
||||
end;
|
||||
'%':
|
||||
begin
|
||||
Inc(TokenStr);
|
||||
If Tokenstr[0]='=' then
|
||||
begin
|
||||
Inc(TokenStr);
|
||||
Result := tjsModEq;
|
||||
end
|
||||
else
|
||||
Result := tjsMod;
|
||||
end;
|
||||
'^':
|
||||
begin
|
||||
Inc(TokenStr);
|
||||
If (TokenStr[0]='=') then
|
||||
begin
|
||||
Result:=tjsXorEq;
|
||||
Inc(tokenStr)
|
||||
end
|
||||
else
|
||||
result:=tjsXOR;
|
||||
end;
|
||||
'|':
|
||||
begin
|
||||
Inc(TokenStr);
|
||||
If Tokenstr[0]='|' then
|
||||
begin
|
||||
Inc(TokenStr);
|
||||
Result := tjsOROR;
|
||||
end
|
||||
else If Tokenstr[0]='=' then
|
||||
begin
|
||||
Inc(TokenStr);
|
||||
Result := tjsOREQ;
|
||||
end
|
||||
else
|
||||
Result := tjsOR;
|
||||
end;
|
||||
'(':
|
||||
begin
|
||||
Inc(TokenStr);
|
||||
Result := tjsBraceOpen;
|
||||
end;
|
||||
')':
|
||||
begin
|
||||
Inc(TokenStr);
|
||||
Result := tjsBraceClose;
|
||||
end;
|
||||
'*':
|
||||
begin
|
||||
Inc(TokenStr);
|
||||
If (TokenStr[0]='=') then
|
||||
begin
|
||||
Inc(TokenStr);
|
||||
Result := tjsMulEq;
|
||||
end
|
||||
else
|
||||
Result := tjsMul;
|
||||
end;
|
||||
'+':
|
||||
begin
|
||||
Inc(TokenStr);
|
||||
If (TokenStr[0]='=') then
|
||||
begin
|
||||
Inc(TokenStr);
|
||||
Result := tjsPlusEq;
|
||||
end
|
||||
else If (TokenStr[0]='+') then
|
||||
begin
|
||||
Inc(TokenStr);
|
||||
Result := tjsPlusPlus;
|
||||
end
|
||||
else
|
||||
Result := tjsPlus;
|
||||
end;
|
||||
',':
|
||||
begin
|
||||
Inc(TokenStr);
|
||||
Result := tjsComma;
|
||||
end;
|
||||
'-':
|
||||
begin
|
||||
Inc(TokenStr);
|
||||
If (TokenStr[0]='=') then
|
||||
begin
|
||||
Inc(TokenStr);
|
||||
Result:=tjsMinusEq
|
||||
end
|
||||
else If (TokenStr[0]='-') then
|
||||
begin
|
||||
Inc(TokenStr);
|
||||
Result:=tjsMinusMinus
|
||||
end
|
||||
else if (TokenStr[0] in ['0'..'9']) then
|
||||
begin
|
||||
Result:=DoNumericLiteral;
|
||||
If (Result=tjsNumber) then
|
||||
FCurTokenString:='-'+FCurTokenString;
|
||||
end
|
||||
else
|
||||
Result := tjsMinus;
|
||||
end;
|
||||
'.':
|
||||
begin
|
||||
Inc(TokenStr);
|
||||
Result := tjsDot;
|
||||
end;
|
||||
':':
|
||||
begin
|
||||
Inc(TokenStr);
|
||||
Result := tjsColon;
|
||||
end;
|
||||
';':
|
||||
begin
|
||||
Inc(TokenStr);
|
||||
Result := tjsSemicolon;
|
||||
end;
|
||||
'<':
|
||||
begin
|
||||
Inc(TokenStr);
|
||||
if TokenStr[0] = '=' then
|
||||
begin
|
||||
Inc(TokenStr);
|
||||
Result := tjsLE;
|
||||
end
|
||||
else if TokenStr[0] = '<' then
|
||||
begin
|
||||
Inc(TokenStr);
|
||||
if (TokenStr[0] = '=') then
|
||||
begin
|
||||
Inc(TokenStr);
|
||||
Result := tjsLShiftEq;
|
||||
end
|
||||
else
|
||||
Result := tjsLShift;
|
||||
end
|
||||
else
|
||||
Result := tjsLT;
|
||||
end;
|
||||
'=':
|
||||
begin
|
||||
Inc(TokenStr);
|
||||
if (TokenStr[0]='=') then
|
||||
begin
|
||||
Inc(TokenStr);
|
||||
If (TokenStr[0]='=') then
|
||||
begin
|
||||
Inc(TokenStr);
|
||||
Result:=tjsSEQ;
|
||||
end
|
||||
else
|
||||
Result:=tjsEQ;
|
||||
end
|
||||
else
|
||||
Result := tjsAssign;
|
||||
end;
|
||||
'!':
|
||||
begin
|
||||
Inc(TokenStr);
|
||||
if (TokenStr[0]='=') then
|
||||
begin
|
||||
Inc(TokenStr);
|
||||
If (TokenStr[0]='=') then
|
||||
begin
|
||||
Inc(TokenStr);
|
||||
Result:=tjsSNE;
|
||||
end
|
||||
else
|
||||
Result:=tjsNE;
|
||||
end
|
||||
else
|
||||
Result:=tjsNot;// Error(SErrInvalidNonEqual);
|
||||
end;
|
||||
'~':
|
||||
begin
|
||||
Inc(TokenStr);
|
||||
Result:=tjsInv;
|
||||
end;
|
||||
'>':
|
||||
begin
|
||||
Inc(TokenStr);
|
||||
if TokenStr[0] = '=' then
|
||||
begin
|
||||
Inc(TokenStr);
|
||||
Result:=tjsGE;
|
||||
end
|
||||
else if TokenStr[0] = '>' then
|
||||
begin
|
||||
Inc(TokenStr);
|
||||
if (TokenStr[0] = '>') then
|
||||
begin
|
||||
Inc(TokenStr);
|
||||
if (TokenStr[0] = '=') then
|
||||
begin
|
||||
Inc(TokenStr);
|
||||
Result:=tjsURSHIFTEQ;
|
||||
end
|
||||
else
|
||||
Result:=tjsURSHIFT;
|
||||
end
|
||||
else if (TokenStr[0] = '=') then
|
||||
begin
|
||||
Inc(TokenStr);
|
||||
Result:=tjsRSHIFTEq;
|
||||
end
|
||||
else
|
||||
Result:=tjsRSHIFT;
|
||||
end
|
||||
else
|
||||
Result := tjsGT;
|
||||
end;
|
||||
'[':
|
||||
begin
|
||||
Inc(TokenStr);
|
||||
Result := tJSSquaredBraceOpen;
|
||||
end;
|
||||
']':
|
||||
begin
|
||||
Inc(TokenStr);
|
||||
Result := tJSSquaredBraceClose;
|
||||
end;
|
||||
'{':
|
||||
begin
|
||||
Inc(TokenStr);
|
||||
Result := tJSCurlyBraceOpen;
|
||||
end;
|
||||
'}':
|
||||
begin
|
||||
Inc(TokenStr);
|
||||
Result := tJSCurlyBraceClose;
|
||||
end;
|
||||
else
|
||||
Result:=DoIdentifier;
|
||||
end; // Case
|
||||
Until (Not (Result in [tjsComment,tjsWhitespace])) or
|
||||
((Result=tjsComment) and ReturnComments) or
|
||||
((Result=tjsWhiteSpace) and ReturnWhiteSpace);
|
||||
FCurToken:=Result;
|
||||
|
||||
end;
|
||||
|
||||
function TJSScanner.IsEndOfLine: Boolean;
|
||||
begin
|
||||
Result:=(TokenStr=Nil) or (TokenStr[0] in [#0,#10,#13]);
|
||||
end;
|
||||
|
||||
function TJSScanner.GetCurColumn: Integer;
|
||||
begin
|
||||
Result := TokenStr - PChar(CurLine);
|
||||
end;
|
||||
|
||||
{ TStreamLineReader }
|
||||
|
||||
constructor TStreamLineReader.Create(AStream: TStream);
|
||||
begin
|
||||
FStream:=AStream;
|
||||
FBufPos:=0;
|
||||
FBufLen:=0;
|
||||
end;
|
||||
|
||||
function TStreamLineReader.IsEOF: Boolean;
|
||||
begin
|
||||
Result:=(FBufPos>=FBufLen);
|
||||
If Result then
|
||||
begin
|
||||
FillBuffer;
|
||||
Result:=(FBufLen=0);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TStreamLineReader.FillBuffer;
|
||||
|
||||
begin
|
||||
FBufLen:=FStream.Read(Buffer,SizeOf(Buffer)-1);
|
||||
Buffer[FBufLen]:=0;
|
||||
FBufPos:=0;
|
||||
end;
|
||||
|
||||
function TStreamLineReader.ReadLine: string;
|
||||
|
||||
Var
|
||||
FPos,OLen,Len: Integer;
|
||||
PRun : PByte;
|
||||
|
||||
begin
|
||||
FPos:=FBufPos;
|
||||
SetLength(Result,0);
|
||||
Repeat
|
||||
PRun:=@Buffer[FBufPos];
|
||||
While (FBufPos<FBufLen) and Not (PRun^ in [10,13]) do
|
||||
begin
|
||||
Inc(PRun);
|
||||
Inc(FBufPos);
|
||||
end;
|
||||
If (FBufPos=FBufLen) then
|
||||
begin
|
||||
Len:=FBufPos-FPos;
|
||||
If (Len>0) then
|
||||
begin
|
||||
Olen:=Length(Result);
|
||||
SetLength(Result,OLen+Len);
|
||||
Move(Buffer[FPos],Result[OLen+1],Len)
|
||||
end;
|
||||
FillBuffer;
|
||||
end;
|
||||
until (FBufPos=FBufLen) or (PRun^ in [10,13]);
|
||||
Len:=FBufPos-FPos;
|
||||
If (Len>0) then
|
||||
begin
|
||||
Olen:=Length(Result);
|
||||
SetLength(Result,OLen+Len);
|
||||
Move(Buffer[FPos],Result[OLen+1],Len)
|
||||
end;
|
||||
If (PRun^ in [10,13]) and (FBufPos<FBufLen) then
|
||||
begin
|
||||
Inc(FBufPos);
|
||||
// Check #13#10
|
||||
If (PRun^=13) then
|
||||
begin
|
||||
If (FBufPos=FBufLen) then
|
||||
FillBuffer;
|
||||
If (FBufPos<FBufLen) and (Buffer[FBufpos]=10) then
|
||||
Inc(FBufPos);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
963
packages/fcl-js/src/jstree.pp
Normal file
963
packages/fcl-js/src/jstree.pp
Normal file
@ -0,0 +1,963 @@
|
||||
unit jstree;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, jsbase;
|
||||
|
||||
Type
|
||||
TJSElementFlag = (elIsConst,elIsConstValid);
|
||||
TJSElementFlags = set of TJSElementFlag;
|
||||
|
||||
TJSFunctionBody = Class;
|
||||
|
||||
{ TJSElement }
|
||||
|
||||
TJSObject = Class(TObject);
|
||||
|
||||
{ TJSFuncDef }
|
||||
|
||||
TJSFuncDef = Class(TJSObject)
|
||||
private
|
||||
FBody: TJSFunctionBody;
|
||||
FCache: TJSObject;
|
||||
FCommon: TJSObject;
|
||||
FIsEmpty: Boolean;
|
||||
FName: String;
|
||||
FNext: TJSFuncDef;
|
||||
FParams: TStrings;
|
||||
FSec: TObject;
|
||||
procedure SetParams(const AValue: TStrings);
|
||||
Public
|
||||
Constructor Create;
|
||||
Destructor Destroy; override;
|
||||
Property Params : TStrings Read FParams Write SetParams;
|
||||
Property Body : TJSFunctionBody Read FBody Write FBody;
|
||||
Property Name : String Read FName Write FName;
|
||||
Property Common : TJSObject Read FCommon Write FCommon;
|
||||
Property Cache : TJSObject Read FCache write FCache;
|
||||
Property Next : TJSFuncDef Read FNext Write FNext;
|
||||
Property IsEmpty : Boolean Read FIsEmpty Write FIsEmpty;
|
||||
Property SecurityDomain : TObject Read FSec Write FSec;
|
||||
end;
|
||||
|
||||
TJSString = WideString;
|
||||
|
||||
TJSElement = Class (TJSObject)
|
||||
private
|
||||
FFlags: TJSElementFlags;
|
||||
FLine: Integer;
|
||||
FRow: Integer;
|
||||
FSource: String;
|
||||
Public
|
||||
Constructor Create(ALine,ARow : Integer; Const ASource : String = ''); virtual;
|
||||
Property Source : String Read FSource Write FSource;
|
||||
Property Row : Integer Read FRow Write FRow;
|
||||
Property Line : Integer Read FLine Write FLine;
|
||||
Property Flags : TJSElementFlags Read FFlags Write FFlags;
|
||||
end;
|
||||
TJSElementClass = Class of TJSElement;
|
||||
|
||||
{ TJSEmptyBlockStatement }
|
||||
|
||||
TJSEmptyBlockStatement = Class(TJSElement);
|
||||
TJSEmptyStatement = Class(TJSElement);
|
||||
|
||||
{ TJSLiteral }
|
||||
|
||||
TJSLiteral = Class(TJSElement)
|
||||
private
|
||||
FValue: TJSValue;
|
||||
Public
|
||||
Constructor Create(ALine,ARow : Integer; Const ASource : String = ''); override;
|
||||
Destructor Destroy; override;
|
||||
Property Value : TJSValue Read FValue Write FValue;
|
||||
end;
|
||||
|
||||
{ TJSStringLiteral }
|
||||
|
||||
TJSStringLiteral = Class(TJSElement)
|
||||
private
|
||||
FValue: TJSString;
|
||||
Public
|
||||
Property Value : TJSString Read FValue Write FValue;
|
||||
end;
|
||||
|
||||
{ TJSRegularExpressionLiteral }
|
||||
|
||||
TJSRegularExpressionLiteral = Class(TJSElement)
|
||||
private
|
||||
FPattern: TJSValue;
|
||||
FPatternFlags: TJSValue;
|
||||
FArgv : Array[0..1] of TJSValue;
|
||||
function GetA(AIndex : integer): TJSValue;
|
||||
procedure SetA(AIndex : integer; const AValue: TJSValue);
|
||||
Public
|
||||
Constructor Create(ALine,ARow : Integer; Const ASource : String = ''); override;
|
||||
Destructor Destroy; override;
|
||||
Property Pattern : TJSValue Read FPattern Write FPattern;
|
||||
Property PatternFlags : TJSValue Read FPatternFlags Write FPatternFlags;
|
||||
Property Argv[AIndex : integer] : TJSValue Read GetA Write SetA;
|
||||
end;
|
||||
|
||||
{ TJSPrimaryExpressionIdent }
|
||||
|
||||
TJSPrimaryExpressionIdent = Class(TJSElement)
|
||||
private
|
||||
FString: TJSString;
|
||||
Public
|
||||
Property AString : TJSString Read FString Write FString;
|
||||
end;
|
||||
TJSPrimaryExpressionThis = Class(TJSElement);
|
||||
|
||||
{ TJSArrayLiteralElement }
|
||||
|
||||
TJSArrayLiteralElement = Class(TCollectionItem)
|
||||
private
|
||||
FExpr: TJSelement;
|
||||
FFindex: Integer;
|
||||
Public
|
||||
Destructor Destroy; override;
|
||||
Property Expr : TJSelement Read FExpr Write FExpr;
|
||||
Property ElementIndex : Integer Read FFindex Write FFIndex;
|
||||
end;
|
||||
|
||||
{ TJSArrayLiteralElements }
|
||||
|
||||
TJSArrayLiteralElements = Class(TCollection)
|
||||
private
|
||||
function GetE(AIndex : Integer): TJSArrayLiteralElement;
|
||||
procedure SetE(AIndex : Integer; const AValue: TJSArrayLiteralElement);
|
||||
Public
|
||||
Function AddElement : TJSArrayLiteralElement;
|
||||
Property Elements[AIndex : Integer] : TJSArrayLiteralElement Read GetE Write SetE; default;
|
||||
end;
|
||||
|
||||
{ TJSArrayLiteral }
|
||||
|
||||
TJSArrayLiteral = Class(TJSElement)
|
||||
private
|
||||
FElements: TJSArrayLiteralElements;
|
||||
Public
|
||||
Constructor Create(ALine,ARow : Integer; const ASource : String = ''); override;
|
||||
Destructor Destroy; override;
|
||||
Property Elements : TJSArrayLiteralElements Read FElements;
|
||||
end;
|
||||
|
||||
{ TJSObjectLiteralElement }
|
||||
|
||||
TJSObjectLiteralElement = Class(TCollectionItem)
|
||||
private
|
||||
FExpr: TJSelement;
|
||||
FName: TJSString;
|
||||
Public
|
||||
Destructor Destroy; override;
|
||||
Property Expr : TJSelement Read FExpr Write FExpr;
|
||||
Property Name : TJSString Read FName Write FName;
|
||||
end;
|
||||
|
||||
{ TJSObjectLiteralElements }
|
||||
|
||||
TJSObjectLiteralElements = Class(TCollection)
|
||||
private
|
||||
function GetE(AIndex : Integer): TJSObjectLiteralElement;
|
||||
procedure SetE(AIndex : Integer; const AValue: TJSObjectLiteralElement);
|
||||
Public
|
||||
Function AddElement : TJSObjectLiteralElement;
|
||||
Property Elements[AIndex : Integer] : TJSObjectLiteralElement Read GetE Write SetE; default;
|
||||
end;
|
||||
|
||||
{ TJSObjectLiteral }
|
||||
|
||||
TJSObjectLiteral = Class(TJSElement)
|
||||
private
|
||||
FElements: TJSObjectLiteralElements;
|
||||
Public
|
||||
Constructor Create(ALine,ARow : Integer; const ASource : String = ''); override;
|
||||
Destructor Destroy; override;
|
||||
Property Elements : TJSObjectLiteralElements Read FElements;
|
||||
end;
|
||||
|
||||
{ TJSArguments }
|
||||
|
||||
TJSArguments = Class(TJSArrayLiteral);
|
||||
|
||||
{ TJSMemberExpression }
|
||||
|
||||
TJSMemberExpression = Class(TJSElement)
|
||||
private
|
||||
FMexpr: TJSElement;
|
||||
Public
|
||||
Destructor Destroy; override;
|
||||
Property Mexpr : TJSElement Read FMexpr Write FMexpr;
|
||||
end;
|
||||
|
||||
{ TJSNewMemberExpression }
|
||||
|
||||
TJSNewMemberExpression = Class(TJSMemberExpression)
|
||||
private
|
||||
FArgs: TJSArguments;
|
||||
Public
|
||||
Destructor Destroy; override;
|
||||
Property Args : TJSArguments Read FArgs Write FArgs;
|
||||
end;
|
||||
|
||||
{ TJSDotMemberExpression }
|
||||
|
||||
TJSDotMemberExpression = Class(TJSMemberExpression)
|
||||
private
|
||||
FName: TJSString;
|
||||
Public
|
||||
Property Name : TJSString Read FName Write FName;
|
||||
end;
|
||||
|
||||
{ TJSBracketMemberExpression }
|
||||
|
||||
TJSBracketMemberExpression = Class(TJSMemberExpression)
|
||||
private
|
||||
FName: TJSElement;
|
||||
Public
|
||||
Destructor Destroy; override;
|
||||
Property Name : TJSElement Read FName Write FName;
|
||||
end;
|
||||
|
||||
{ TJSCallExpression }
|
||||
|
||||
TJSCallExpression = Class(TJSElement)
|
||||
private
|
||||
FArgs: TJSArguments;
|
||||
FExpr: TJSElement;
|
||||
Public
|
||||
Destructor Destroy; override;
|
||||
Property Expr : TJSElement Read FExpr Write FExpr;
|
||||
Property Args : TJSArguments Read FArgs Write FArgs;
|
||||
end;
|
||||
|
||||
{ TJSUnary }
|
||||
|
||||
TJSUnary = Class(TJSElement)
|
||||
private
|
||||
FA: TJSElement;
|
||||
Public
|
||||
Destructor Destroy; override;
|
||||
Property A : TJSElement Read FA Write FA;
|
||||
end;
|
||||
|
||||
{ TJSVariableStatement }
|
||||
TJSVariableStatement = Class(TJSUnary);
|
||||
TJSExpressionStatement = Class(TJSUnary);
|
||||
TJSThrowStatement = Class(TJSUnary);
|
||||
TJSUnaryExpression = Class(TJSUnary);
|
||||
TJSUnaryDeleteExpression = Class(TJSUnaryExpression);
|
||||
TJSUnaryVoidExpression = Class(TJSUnaryExpression);
|
||||
TJSUnaryTypeOfExpression = Class(TJSUnaryExpression);
|
||||
TJSUnaryPrePlusPlusExpression = Class(TJSUnaryExpression);
|
||||
TJSUnaryPreMinusMinusExpression = Class(TJSUnaryExpression);
|
||||
TJSUnaryPlusExpression = Class(TJSUnaryExpression);
|
||||
TJSUnaryMinusExpression = Class(TJSUnaryExpression);
|
||||
TJSUnaryInvExpression = Class(TJSUnaryExpression);
|
||||
TJSUnaryNotExpression = Class(TJSUnaryExpression);
|
||||
TJSUnaryPostPlusPlusExpression = Class(TJSUnaryExpression);
|
||||
TJSUnaryPostMinusMinusExpression = Class(TJSUnaryExpression);
|
||||
|
||||
|
||||
|
||||
{ TJSBinary }
|
||||
|
||||
TJSBinary = Class(TJSElement)
|
||||
private
|
||||
FA: TJSElement;
|
||||
FB: TJSElement;
|
||||
Public
|
||||
Destructor Destroy; override;
|
||||
Property A : TJSElement Read FA Write FA;
|
||||
Property B : TJSElement Read FB Write FB;
|
||||
end;
|
||||
|
||||
{ TJSStatementList }
|
||||
|
||||
TJSStatementList = Class(TJSBinary); // A->first statement, B->next in list, chained.
|
||||
TJSVariableDeclarationList = Class(TJSBinary);
|
||||
TJSWithStatement = Class(TJSBinary); // A-> with expression, B->statement(s)
|
||||
TJSLogicalOrExpression = Class (TJSBinary);
|
||||
TJSLogicalAndExpression = Class (TJSBinary);
|
||||
TJSBitwiseAndExpression = Class (TJSBinary);
|
||||
TJSBitwiseOrExpression = Class (TJSBinary);
|
||||
TJSBitwiseXOrExpression = Class (TJSBinary);
|
||||
TJSEqualityExpression = Class (TJSBinary);
|
||||
TJSEqualityExpressionEQ = Class(TJSEqualityExpression);
|
||||
TJSEqualityExpressionNE = Class(TJSEqualityExpression);
|
||||
TJSEqualityExpressionSEQ = Class(TJSEqualityExpression);
|
||||
TJSEqualityExpressionSNE = Class(TJSEqualityExpression);
|
||||
TJSRelationalExpression = Class(TJSBinary);
|
||||
TJSRelationalExpressionLT = Class(TJSRelationalExpression);
|
||||
TJSRelationalExpressionGT = Class(TJSRelationalExpression);
|
||||
TJSRelationalExpressionLE = Class(TJSRelationalExpression);
|
||||
TJSRelationalExpressionGE = Class(TJSRelationalExpression);
|
||||
TJSRelationalExpressionIn = Class(TJSRelationalExpression);
|
||||
TJSRelationalExpressionInstanceOf = Class(TJSRelationalExpression);
|
||||
TJSShiftExpression = Class(TJSBinary);
|
||||
TJSLShiftExpression = Class(TJSShiftExpression);
|
||||
TJSRShiftExpression = Class(TJSShiftExpression);
|
||||
TJSURShiftExpression = Class(TJSShiftExpression);
|
||||
TJSAdditiveExpression = Class(TJSBinary);
|
||||
TJSAdditiveExpressionPlus = Class(TJSAdditiveExpression);
|
||||
TJSAdditiveExpressionMinus = Class(TJSAdditiveExpression);
|
||||
TJSMultiplicativeExpression = Class(TJSBinary);
|
||||
TJSMultiplicativeExpressionMul = Class(TJSMultiplicativeExpression);
|
||||
TJSMultiplicativeExpressionDiv = Class(TJSMultiplicativeExpression);
|
||||
TJSMultiplicativeExpressionMod = Class(TJSMultiplicativeExpression);
|
||||
TJSCommaExpression = Class(TJSBinary);
|
||||
|
||||
{ TJSConditionalExpression }
|
||||
|
||||
TJSConditionalExpression = Class(TJSElement)
|
||||
private
|
||||
FA: TJSElement;
|
||||
FB: TJSElement;
|
||||
FC: TJSElement;
|
||||
Public
|
||||
Destructor Destroy; override;
|
||||
Property A : TJSElement Read FA Write FA;
|
||||
Property B : TJSElement Read FB Write FB;
|
||||
Property C : TJSElement Read FC Write FC;
|
||||
end;
|
||||
|
||||
{ TJSAssignStatement }
|
||||
|
||||
TJSAssignStatement = Class(TJSElement)
|
||||
private
|
||||
FExpr: TJSElement;
|
||||
FLHS: TJSElement;
|
||||
Public
|
||||
Destructor Destroy; override;
|
||||
Property Expr : TJSElement Read FExpr Write FExpr;
|
||||
Property LHS : TJSElement Read FLHS Write FLHS;
|
||||
end;
|
||||
|
||||
TJSSimpleAssignStatement = Class(TJSAssignStatement);
|
||||
TJSMulEqAssignStatement = Class(TJSAssignStatement);
|
||||
TJSDivEqAssignStatement = Class(TJSAssignStatement);
|
||||
TJSModEqAssignStatement = Class(TJSAssignStatement);
|
||||
TJSAddEqAssignStatement = Class(TJSAssignStatement);
|
||||
TJSSubEqAssignStatement = Class(TJSAssignStatement);
|
||||
TJSLShiftEqAssignStatement = Class(TJSAssignStatement);
|
||||
TJSRShiftEqAssignStatement = Class(TJSAssignStatement);
|
||||
TJSURShiftEqAssignStatement = Class(TJSAssignStatement);
|
||||
TJSANDEqAssignStatement = Class(TJSAssignStatement);
|
||||
TJSOREqAssignStatement = Class(TJSAssignStatement);
|
||||
TJSXOREqAssignStatement = Class(TJSAssignStatement);
|
||||
|
||||
{ TJSVarDeclaration }
|
||||
|
||||
TJSVarDeclaration = Class(TJSElement)
|
||||
private
|
||||
FInit: TJSElement;
|
||||
FName: String;
|
||||
Public
|
||||
Destructor Destroy; override;
|
||||
Property Name : String Read FName Write FName;
|
||||
Property Init : TJSElement Read FInit Write FInit;
|
||||
end;
|
||||
|
||||
{ TJSIfStatement }
|
||||
|
||||
TJSIfStatement = Class(TJSElement)
|
||||
private
|
||||
FBFalse: TJSElement;
|
||||
FBTrue: TJSElement;
|
||||
FCond: TJSElement;
|
||||
Public
|
||||
Destructor Destroy; override;
|
||||
Property Cond : TJSElement Read FCond Write FCond;
|
||||
Property btrue : TJSElement Read FBTrue Write FBTrue;
|
||||
Property bfalse : TJSElement Read FBFalse Write FBFalse;
|
||||
end;
|
||||
|
||||
{ TJSWhileStatement }
|
||||
|
||||
{ TJSTargetStatement }
|
||||
|
||||
TJSTargetStatement = Class(TJSElement)
|
||||
private
|
||||
FTarget: Cardinal;
|
||||
Public
|
||||
Property Target : Cardinal Read FTarget Write FTarget;
|
||||
end;
|
||||
|
||||
{ TJSBodyStatement }
|
||||
|
||||
TJSBodyStatement = Class(TJSTargetStatement)
|
||||
private
|
||||
FBody: TJSElement;
|
||||
Public
|
||||
Destructor Destroy; override;
|
||||
Property body : TJSElement Read FBody Write FBody;
|
||||
end;
|
||||
|
||||
{ TJSCondLoopStatement }
|
||||
|
||||
TJSCondLoopStatement = Class(TJSBodyStatement)
|
||||
private
|
||||
FCond: TJSElement;
|
||||
Public
|
||||
Destructor Destroy; override;
|
||||
Property Cond : TJSElement Read FCond Write FCond;
|
||||
end;
|
||||
|
||||
TJSWhileStatement = Class(TJSCondLoopStatement)
|
||||
end;
|
||||
|
||||
{ TJSForStatement }
|
||||
|
||||
TJSForStatement = Class(TJSCondLoopStatement)
|
||||
private
|
||||
FIncr: TJSElement;
|
||||
FInit: TJSElement;
|
||||
Public
|
||||
Destructor Destroy; override;
|
||||
Property Incr : TJSElement Read FIncr Write FIncr;
|
||||
Property Init : TJSElement Read FInit Write FInit;
|
||||
end;
|
||||
|
||||
{ TJSForInStatement }
|
||||
|
||||
TJSForInStatement = Class(TJSBodyStatement)
|
||||
private
|
||||
FLhs: TJSElement;
|
||||
FList: TJSElement;
|
||||
Public
|
||||
Destructor Destroy; override;
|
||||
Property LHS : TJSElement Read FLHS Write FLHS;
|
||||
Property List : TJSElement Read FList Write FList;
|
||||
end;
|
||||
|
||||
TJSContinueStatement = Class(TJSTargetStatement);
|
||||
|
||||
TJSBreakStatement = Class(TJSTargetStatement);
|
||||
|
||||
{ TJSReturn }
|
||||
|
||||
TJSReturnStatement = Class(TJSElement)
|
||||
private
|
||||
FExpr: TJSElement;
|
||||
Public
|
||||
Destructor Destroy; override;
|
||||
Property Expr : TJSElement Read FExpr Write FExpr;
|
||||
end;
|
||||
|
||||
{ TJSCaseElement }
|
||||
|
||||
TJSCaseElement = Class(TCollectionItem)
|
||||
private
|
||||
FBody: TJSElement;
|
||||
FExpr: TJSelement;
|
||||
Public
|
||||
Destructor Destroy; override;
|
||||
Property Expr : TJSelement Read FExpr Write FExpr;
|
||||
Property Body : TJSElement Read FBody Write FBody;
|
||||
end;
|
||||
|
||||
{ TJSCaseElements }
|
||||
|
||||
TJSCaseElements = Class(TCollection)
|
||||
private
|
||||
function GetC(AIndex : Integer): TJSCaseElement;
|
||||
procedure SetC(AIndex : Integer; const AValue: TJSCaseElement);
|
||||
Public
|
||||
Function AddCase : TJSCaseElement;
|
||||
Property Cases[AIndex : Integer] : TJSCaseElement Read GetC Write SetC;
|
||||
end;
|
||||
|
||||
{ TJSSwitch }
|
||||
|
||||
TJSSwitchStatement = Class(TJSTargetStatement)
|
||||
private
|
||||
FCases: TJSCaseElements;
|
||||
FCond: TJSelement;
|
||||
FDefault: TJSCaseElement;
|
||||
Public
|
||||
Constructor Create(ALine,ARow : Integer; const ASource : String = ''); override;
|
||||
Destructor Destroy; override;
|
||||
Property Cond : TJSelement Read FCond Write FCond;
|
||||
Property Cases : TJSCaseElements Read FCases;
|
||||
Property TheDefault : TJSCaseelement Read FDefault Write FDefault;
|
||||
end;
|
||||
|
||||
{ TJSLabeledStatement }
|
||||
|
||||
TJSLabeledStatement = Class(TJSUnary)
|
||||
private
|
||||
FTarget: Integer;
|
||||
Public
|
||||
Property target: Integer Read FTarget Write FTarget;
|
||||
end;
|
||||
|
||||
{ TJSTryStatement }
|
||||
|
||||
TJSTryStatement = Class(TJSElement)
|
||||
private
|
||||
FBCatch: TJSElement;
|
||||
FBFinally: TJSElement;
|
||||
FBlock: TJSElement;
|
||||
FIdent: TJSString;
|
||||
Public
|
||||
Destructor Destroy; override;
|
||||
Property Block : TJSElement Read FBlock Write FBlock;
|
||||
Property BCatch : TJSElement Read FBCatch Write FBCatch;
|
||||
Property BFinally : TJSElement Read FBFinally Write FBFinally;
|
||||
Property Ident : TJSString Read FIdent Write FIDent;
|
||||
end;
|
||||
|
||||
TJSTryCatchFinallyStatement = Class(TJSTryStatement);
|
||||
TJSTryCatchStatement = Class(TJSTryStatement);
|
||||
TJSTryFinallyStatement = Class(TJSTryStatement);
|
||||
|
||||
|
||||
{ TJSFunction }
|
||||
|
||||
TJSFunctionDeclarationStatement = Class(TJSelement)
|
||||
private
|
||||
FFuncDef: TJSFuncDef;
|
||||
Public
|
||||
Destructor Destroy; override;
|
||||
Property AFunction : TJSFuncDef Read FFuncDef Write FFuncDef;
|
||||
end;
|
||||
|
||||
{ TJSFunctionBody }
|
||||
|
||||
TJSFunctionBody = Class(TJSUnary)
|
||||
private
|
||||
FisProgram: Boolean;
|
||||
Public
|
||||
Property isProgram : Boolean Read FisProgram Write FIsProgram;
|
||||
end;
|
||||
|
||||
{ TJSElementNode }
|
||||
|
||||
TJSElementNode = Class(TCollectionItem)
|
||||
private
|
||||
FNode: TJSElement;
|
||||
Public
|
||||
Destructor Destroy; override;
|
||||
Property Node : TJSElement Read FNode Write FNode;
|
||||
end;
|
||||
|
||||
{ TJSElementNodes }
|
||||
|
||||
TJSElementNodes = Class(TCollection)
|
||||
private
|
||||
function GetN(AIndex : Integer): TJSElementNode;
|
||||
procedure SetN(AIndex : Integer; const AValue: TJSElementNode);
|
||||
Public
|
||||
Function AddNode : TJSElementNode;
|
||||
Property Nodes[AIndex : Integer] : TJSElementNode Read GetN Write SetN; default;
|
||||
end;
|
||||
|
||||
{ TJSSourceElements }
|
||||
TJSSourceElements = Class(TJSElement)
|
||||
private
|
||||
FFunctions: TJSElementNodes;
|
||||
FStatements: TJSElementNodes;
|
||||
FVars: TJSElementNodes;
|
||||
Public
|
||||
Constructor Create(ALine,ARow : Integer; const ASource : String = ''); override;
|
||||
Destructor Destroy; override;
|
||||
Property Statements : TJSElementNodes Read FStatements;
|
||||
Property functions : TJSElementNodes Read FFunctions;
|
||||
Property Vars : TJSElementNodes Read FVars;
|
||||
end;
|
||||
|
||||
|
||||
implementation
|
||||
|
||||
{ TJSElement }
|
||||
|
||||
constructor TJSElement.Create(ALine, ARow: Integer; Const ASource: String = '');
|
||||
begin
|
||||
FLine:=ALine;
|
||||
FRow:=ARow;
|
||||
FSource:=ASource;
|
||||
end;
|
||||
|
||||
{ TJSRegularExpressionLiteral }
|
||||
|
||||
function TJSRegularExpressionLiteral.GetA(AIndex : integer): TJSValue;
|
||||
begin
|
||||
Result:=FArgv[AIndex];
|
||||
end;
|
||||
|
||||
procedure TJSRegularExpressionLiteral.SetA(AIndex : integer;
|
||||
const AValue: TJSValue);
|
||||
begin
|
||||
FArgv[AIndex]:=Avalue;
|
||||
end;
|
||||
|
||||
constructor TJSRegularExpressionLiteral.Create(ALine, ARow: Integer;
|
||||
const ASource: String);
|
||||
begin
|
||||
inherited Create(ALine, ARow, ASource);
|
||||
FPattern:=TJSValue.Create;
|
||||
FPatternFlags:=TJSValue.Create;
|
||||
end;
|
||||
|
||||
destructor TJSRegularExpressionLiteral.Destroy;
|
||||
begin
|
||||
FreeAndNil(FPattern);
|
||||
FreeAndNil(FPatternFlags);
|
||||
Inherited Destroy;
|
||||
end;
|
||||
|
||||
{ TJSArrayLiteralElements }
|
||||
|
||||
function TJSArrayLiteralElements.GetE(AIndex : Integer): TJSArrayLiteralElement;
|
||||
begin
|
||||
Result:=TJSArrayLiteralElement(Items[AIndex]);
|
||||
end;
|
||||
|
||||
procedure TJSArrayLiteralElements.SetE(AIndex : Integer;
|
||||
const AValue: TJSArrayLiteralElement);
|
||||
begin
|
||||
Items[AIndex]:=AValue;
|
||||
end;
|
||||
|
||||
function TJSArrayLiteralElements.AddElement: TJSArrayLiteralElement;
|
||||
begin
|
||||
Result:=TJSArrayLiteralElement(Add);
|
||||
end;
|
||||
|
||||
{ TJSArrayLiteral }
|
||||
|
||||
constructor TJSArrayLiteral.Create(ALine, ARow: Integer; Const ASource: String = '');
|
||||
begin
|
||||
inherited Create(ALine, ARow, ASource);
|
||||
FElements:=TJSArrayLiteralElements.Create(TJSArrayLiteralElement);
|
||||
end;
|
||||
|
||||
destructor TJSArrayLiteral.Destroy;
|
||||
begin
|
||||
FreeAndNil(FElements);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
{ TJSObjectLiteralElements }
|
||||
|
||||
function TJSObjectLiteralElements.GetE(AIndex : Integer
|
||||
): TJSObjectLiteralElement;
|
||||
begin
|
||||
Result:=TJSObjectLiteralElement(Items[AIndex]);
|
||||
end;
|
||||
|
||||
procedure TJSObjectLiteralElements.SetE(AIndex : Integer;
|
||||
const AValue: TJSObjectLiteralElement);
|
||||
begin
|
||||
Items[AIndex]:=AValue;
|
||||
end;
|
||||
|
||||
function TJSObjectLiteralElements.AddElement: TJSObjectLiteralElement;
|
||||
begin
|
||||
Result:=TJSObjectLiteralElement(Add);
|
||||
end;
|
||||
|
||||
{ TJSObjectLiteral }
|
||||
|
||||
constructor TJSObjectLiteral.Create(ALine, ARow: Integer; const ASource: String = '');
|
||||
begin
|
||||
inherited Create(ALine, ARow, ASource);
|
||||
FElements:=TJSObjectLiteralElements.Create(TJSObjectLiteralElement);
|
||||
end;
|
||||
|
||||
destructor TJSObjectLiteral.Destroy;
|
||||
begin
|
||||
FreeAndNil(FElements);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
{ TJSObjectLiteralElement }
|
||||
|
||||
destructor TJSObjectLiteralElement.Destroy;
|
||||
begin
|
||||
FreeAndNil(Fexpr);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
{ TJSArrayLiteralElement }
|
||||
|
||||
destructor TJSArrayLiteralElement.Destroy;
|
||||
begin
|
||||
FreeAndNil(Fexpr);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
{ TJSNewMemberExpression }
|
||||
|
||||
destructor TJSNewMemberExpression.Destroy;
|
||||
begin
|
||||
FreeAndNil(FArgs);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
{ TJSMemberExpression }
|
||||
|
||||
destructor TJSMemberExpression.Destroy;
|
||||
begin
|
||||
FreeAndNil(FMExpr);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
{ TJSCallExpression }
|
||||
|
||||
destructor TJSCallExpression.Destroy;
|
||||
begin
|
||||
FreeAndNil(FExpr);
|
||||
FreeAndNil(FArgs);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
{ TJSUnary }
|
||||
|
||||
destructor TJSUnary.Destroy;
|
||||
begin
|
||||
FreeAndNil(FA);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
{ TJSBinary }
|
||||
|
||||
destructor TJSBinary.Destroy;
|
||||
begin
|
||||
FreeAndNil(FB);
|
||||
FreeAndNil(FA);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
{ TJSConditionalExpression }
|
||||
|
||||
destructor TJSConditionalExpression.Destroy;
|
||||
begin
|
||||
FreeAndNil(FB);
|
||||
FreeAndNil(FA);
|
||||
FreeAndNil(FC);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
{ TJSAssign }
|
||||
|
||||
destructor TJSAssignStatement.Destroy;
|
||||
begin
|
||||
FreeAndNil(FLHS);
|
||||
FreeAndNil(FExpr);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
{ TJSVarDeclaration }
|
||||
|
||||
|
||||
destructor TJSVarDeclaration.Destroy;
|
||||
begin
|
||||
FreeAndNil(FInit);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
{ TJSIfStatement }
|
||||
|
||||
destructor TJSIfStatement.Destroy;
|
||||
begin
|
||||
FreeAndNil(FCond);
|
||||
FreeAndNil(FBTrue);
|
||||
FreeAndNil(FBFalse);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
{ TJSBodyStatement }
|
||||
|
||||
destructor TJSBodyStatement.Destroy;
|
||||
begin
|
||||
FreeAndNil(FBody);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
{ TJSCondLoopStatement }
|
||||
|
||||
destructor TJSCondLoopStatement.Destroy;
|
||||
begin
|
||||
FreeAndNil(FCond);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
{ TJSForStatement }
|
||||
|
||||
destructor TJSForStatement.Destroy;
|
||||
begin
|
||||
FreeAndNil(FIncr);
|
||||
FreeAndNil(FInit);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
{ TJSForInStatement }
|
||||
|
||||
destructor TJSForInStatement.Destroy;
|
||||
begin
|
||||
FreeAndNil(FList);
|
||||
FreeAndNil(FLHS);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
|
||||
{ TJSReturn }
|
||||
|
||||
destructor TJSReturnStatement.Destroy;
|
||||
begin
|
||||
FreeAndNil(FExpr);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
{ TJSCaseElement }
|
||||
|
||||
destructor TJSCaseElement.Destroy;
|
||||
begin
|
||||
FreeAndNil(FExpr);
|
||||
FreeAndNil(FBody);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
{ TJSSwitch }
|
||||
|
||||
constructor TJSSwitchStatement.Create(ALine, ARow: Integer; const ASource: String);
|
||||
begin
|
||||
inherited Create(ALine, ARow, ASource);
|
||||
FCases:=TJSCaseElements.Create(TJSCaseElement);
|
||||
end;
|
||||
|
||||
destructor TJSSwitchStatement.Destroy;
|
||||
begin
|
||||
FreeAndNil(FCases);
|
||||
FreeAndNil(FDefault);
|
||||
FreeAndNil(FCond);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
{ TJSCaseElements }
|
||||
|
||||
function TJSCaseElements.GetC(AIndex : Integer): TJSCaseElement;
|
||||
begin
|
||||
Result:=TJSCaseElement(Items[AIndex]);
|
||||
end;
|
||||
|
||||
procedure TJSCaseElements.SetC(AIndex : Integer; const AValue: TJSCaseElement);
|
||||
begin
|
||||
Items[AIndex]:=AValue;
|
||||
end;
|
||||
|
||||
function TJSCaseElements.AddCase: TJSCaseElement;
|
||||
begin
|
||||
Result:=TJSCaseElement(Add);
|
||||
end;
|
||||
|
||||
{ TJSTryStatement }
|
||||
|
||||
destructor TJSTryStatement.Destroy;
|
||||
begin
|
||||
FreeAndNil(FBlock);
|
||||
FreeAndNil(FBCatch);
|
||||
FreeAndNil(FBFinally);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
{ TJSSourceElements }
|
||||
|
||||
constructor TJSSourceElements.Create(ALine, ARow: Integer; const ASource: String
|
||||
);
|
||||
begin
|
||||
inherited Create(ALine, ARow, ASource);
|
||||
FStatements:=TJSElementNodes.Create(TJSElementNode);
|
||||
FFunctions:=TJSElementNodes.Create(TJSElementNode);
|
||||
FVars:=TJSElementNodes.Create(TJSElementNode);
|
||||
end;
|
||||
|
||||
destructor TJSSourceElements.Destroy;
|
||||
begin
|
||||
FreeAndNil(FStatements);
|
||||
FreeAndNil(FFunctions);
|
||||
FreeAndNil(FVars);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
{ TJSElementNodes }
|
||||
|
||||
function TJSElementNodes.GetN(AIndex : Integer): TJSElementNode;
|
||||
begin
|
||||
Result:=TJSElementNode(Items[Aindex])
|
||||
end;
|
||||
|
||||
procedure TJSElementNodes.SetN(AIndex : Integer; const AValue: TJSElementNode);
|
||||
begin
|
||||
Items[AIndex]:=Avalue;
|
||||
end;
|
||||
|
||||
function TJSElementNodes.AddNode: TJSElementNode;
|
||||
begin
|
||||
Result:=TJSElementNode(Add);
|
||||
end;
|
||||
|
||||
{ TJSFunction }
|
||||
|
||||
destructor TJSFunctionDeclarationStatement.Destroy;
|
||||
begin
|
||||
FreeAndNil(FFuncDef);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
{ TJSElementNode }
|
||||
|
||||
destructor TJSElementNode.Destroy;
|
||||
begin
|
||||
//FreeAndNil(FNode);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
{ TJSFuncDef }
|
||||
|
||||
procedure TJSFuncDef.SetParams(const AValue: TStrings);
|
||||
begin
|
||||
if FParams=AValue then exit;
|
||||
FParams.Assign(AValue);
|
||||
end;
|
||||
|
||||
constructor TJSFuncDef.Create;
|
||||
begin
|
||||
FParams:=TStringList.Create;
|
||||
end;
|
||||
|
||||
destructor TJSFuncDef.Destroy;
|
||||
begin
|
||||
FreeAndNil(FParams);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
{ TJSBracketMemberExpression }
|
||||
|
||||
destructor TJSBracketMemberExpression.Destroy;
|
||||
begin
|
||||
FreeAndNil(FName);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
{ TJSLiteral }
|
||||
|
||||
constructor TJSLiteral.Create(ALine, ARow: Integer; const ASource: String);
|
||||
begin
|
||||
FValue:=TJSValue.Create;
|
||||
inherited Create(ALine, ARow, ASource);
|
||||
end;
|
||||
|
||||
destructor TJSLiteral.Destroy;
|
||||
begin
|
||||
FreeAndNil(FValue);
|
||||
Inherited;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
2311
packages/fcl-js/tests/tcparser.pp
Normal file
2311
packages/fcl-js/tests/tcparser.pp
Normal file
File diff suppressed because it is too large
Load Diff
983
packages/fcl-js/tests/tcscanner.pp
Normal file
983
packages/fcl-js/tests/tcscanner.pp
Normal file
@ -0,0 +1,983 @@
|
||||
unit tcscanner;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, Typinfo, fpcunit, testutils, testregistry, jsscanner;
|
||||
|
||||
type
|
||||
|
||||
{ TTestLineReader }
|
||||
|
||||
TTestLineReader = Class(TTestCase)
|
||||
Private
|
||||
FData: TStringStream;
|
||||
FReader : TStreamLineReader;
|
||||
protected
|
||||
Procedure CreateReader(AInput : String);
|
||||
procedure TearDown; override;
|
||||
published
|
||||
Procedure TestEmpty;
|
||||
Procedure TestReadLine;
|
||||
Procedure TestReadLines13;
|
||||
Procedure TestReadLines10;
|
||||
Procedure TestReadLines1310;
|
||||
procedure TestReadLinesEOF13;
|
||||
procedure TestReadLinesEOF10;
|
||||
procedure TestReadLinesEOF1310;
|
||||
procedure TestReadEmptyLines101010;
|
||||
end;
|
||||
|
||||
{ TTestJSScanner }
|
||||
|
||||
TTestJSScanner = class(TTestCase)
|
||||
Private
|
||||
FStream : TStream;
|
||||
FLineReader : TLineReader;
|
||||
FScanner : TJSScanner;
|
||||
FErrorSource : String;
|
||||
procedure AssertEquals(AMessage: String; AExpected, AActual : TJSToken); overload;
|
||||
procedure CheckToken(AToken: TJSToken; ASource: String);
|
||||
procedure CheckTokens(ASource: String; ATokens: array of TJSToken);
|
||||
procedure DoTestFloat(F: Double);
|
||||
procedure DoTestFloat(F: Double; S: String);
|
||||
procedure DoTestString(S: String);
|
||||
procedure TestErrorSource;
|
||||
protected
|
||||
Function CreateScanner(AInput : String) : TJSScanner;
|
||||
procedure FreeScanner;
|
||||
procedure SetUp; override;
|
||||
procedure TearDown; override;
|
||||
|
||||
Property Scanner : TJSScanner Read FScanner;
|
||||
published
|
||||
Procedure TestEmpty;
|
||||
procedure TestAndAnd;
|
||||
procedure TestAndEq;
|
||||
procedure TestAssign;
|
||||
procedure TestBraceClose;
|
||||
procedure TestBraceOpen;
|
||||
procedure TestColon;
|
||||
procedure TestComma;
|
||||
procedure TestCurlyBraceClose;
|
||||
procedure TestCurlyBraceOpen;
|
||||
procedure TestDiv;
|
||||
procedure TestDiveq;
|
||||
procedure TestXor;
|
||||
procedure TestXoreq;
|
||||
procedure TestDot;
|
||||
procedure TestEq;
|
||||
procedure TestGE;
|
||||
procedure TestFalse;
|
||||
procedure TestInv;
|
||||
procedure TestNot;
|
||||
procedure TestString;
|
||||
procedure TestTrue;
|
||||
procedure TestGreaterThan;
|
||||
procedure TestLE;
|
||||
procedure TestLessThan;
|
||||
procedure TestLSHIFT;
|
||||
procedure TestLSHIFTEQ;
|
||||
procedure TestMinus;
|
||||
procedure TestMinusEQ;
|
||||
procedure TestMinusMinus;
|
||||
procedure TestModeq;
|
||||
procedure TestMul;
|
||||
procedure TestNE;
|
||||
procedure TestNSE;
|
||||
procedure TestOREQ;
|
||||
procedure TestOROR;
|
||||
procedure TestPlus;
|
||||
procedure TestPlusEq;
|
||||
procedure TestPlusPlus;
|
||||
procedure TestRShift;
|
||||
procedure TestRShiftEq;
|
||||
procedure TestSemicolon;
|
||||
procedure TestSEq;
|
||||
procedure TestSquaredBraceClose;
|
||||
procedure TestSquaredBraceOpen;
|
||||
procedure TestStarEq;
|
||||
procedure TestURShift;
|
||||
procedure TestURShiftEq;
|
||||
procedure TestBreak;
|
||||
procedure TestCase;
|
||||
procedure TestCatch;
|
||||
procedure TestContinue;
|
||||
procedure TestDefault;
|
||||
procedure TestDelete;
|
||||
procedure TestDO;
|
||||
procedure TestElse;
|
||||
procedure TestFinally;
|
||||
procedure TestFor;
|
||||
procedure TestFunction;
|
||||
procedure TestIf;
|
||||
procedure TestIn;
|
||||
procedure TestInstanceOf;
|
||||
procedure TestNew;
|
||||
procedure TestReturn;
|
||||
procedure TestSwitch;
|
||||
procedure TestThis;
|
||||
procedure TestThrow;
|
||||
procedure TestTry;
|
||||
procedure TestTypeOf;
|
||||
procedure TestVar;
|
||||
procedure TestVoid;
|
||||
procedure TestWhile;
|
||||
procedure TestWith;
|
||||
Procedure Test2Words;
|
||||
procedure Test3Words;
|
||||
procedure TestIdentifier;
|
||||
procedure TestIdentifier2;
|
||||
procedure TestIdentifier3;
|
||||
procedure TestIdentifier4;
|
||||
procedure TestIdentifier5;
|
||||
procedure TestIdentifierDotIdentifier;
|
||||
procedure TestEOLN;
|
||||
procedure TestEOLN2;
|
||||
procedure TestEOLN3;
|
||||
procedure TestEOLN4;
|
||||
procedure TestComment1;
|
||||
procedure TestComment2;
|
||||
procedure TestComment3;
|
||||
procedure TestComment4;
|
||||
procedure TestComment5;
|
||||
procedure TestComment6;
|
||||
procedure TestFloat;
|
||||
procedure TestStringError;
|
||||
procedure TestFloatError;
|
||||
end;
|
||||
|
||||
|
||||
implementation
|
||||
|
||||
Function TTestJSScanner.CreateScanner(AInput : String) : TJSScanner;
|
||||
|
||||
begin
|
||||
FStream:=TStringStream.Create(AInput);
|
||||
FLineReader:=TStreamLineReader.Create(Fstream);
|
||||
FScanner:=TJSScanner.Create(FLineReader);
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.FreeScanner;
|
||||
begin
|
||||
FreeAndNil(FScanner);
|
||||
FreeAndNil(FLineReader);
|
||||
FreeAndNil(FStream);
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.SetUp;
|
||||
begin
|
||||
inherited SetUp;
|
||||
end;
|
||||
|
||||
|
||||
|
||||
procedure TTestJSScanner.TestEmpty;
|
||||
|
||||
Var
|
||||
J : TJSToken;
|
||||
|
||||
begin
|
||||
CreateScanner('');
|
||||
J:=Scanner.FetchToken;
|
||||
If (J<>tjsEOF) then
|
||||
Fail('Empty returns EOF');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.AssertEquals(AMessage : String; AExpected, AActual: TJSToken);
|
||||
|
||||
Var
|
||||
J : TJSToken;
|
||||
S,EN1,EN2 : String;
|
||||
|
||||
begin
|
||||
If (AActual<>AExpected) then
|
||||
begin
|
||||
EN1:=GetEnumName(TypeINfo(TJSToken),Ord(AExpected));
|
||||
EN2:=GetEnumName(TypeINfo(TJSToken),Ord(AActual));
|
||||
S:=Format('%s : %s <> %s',[AMessage,EN1,EN2]);
|
||||
Fail(S);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.CheckToken(AToken : TJSToken; ASource : String);
|
||||
|
||||
Var
|
||||
J : TJSToken;
|
||||
EN2 : String;
|
||||
|
||||
begin
|
||||
CreateScanner(ASource);
|
||||
J:=Scanner.FetchToken;
|
||||
EN2:=GetEnumName(TypeINfo(TJSToken),Ord(AToken));
|
||||
AssertEquals(Format('Source %s should result in %s.',[ASource,EN2]),AToken,J);
|
||||
end;
|
||||
|
||||
|
||||
procedure TTestJSScanner.TestAndAnd;
|
||||
|
||||
begin
|
||||
CheckToken(tjsAndAnd,'&&');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestAndEq;
|
||||
|
||||
begin
|
||||
CheckToken(tjsAndEq,'&=');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestBraceOpen;
|
||||
|
||||
begin
|
||||
CheckToken(tjsBraceOpen,'(');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestBraceClose;
|
||||
|
||||
begin
|
||||
CheckToken(tjsBraceClose,')');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestSquaredBraceClose;
|
||||
|
||||
begin
|
||||
CheckToken(tjsSquaredBraceClose,']');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestSquaredBraceOpen;
|
||||
|
||||
begin
|
||||
CheckToken(tjssQuaredBraceOpen,'[');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestCurlyBraceOpen;
|
||||
|
||||
begin
|
||||
CheckToken(tjsCurlyBraceOpen,'{');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestCurlyBraceClose;
|
||||
|
||||
begin
|
||||
CheckToken(tjsCurlyBraceClose,'}');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestComma;
|
||||
|
||||
begin
|
||||
CheckToken(tjsComma,',');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestColon;
|
||||
|
||||
begin
|
||||
CheckToken(tjsColon,':');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestDot;
|
||||
|
||||
begin
|
||||
CheckToken(tjsDot,'.');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestSemicolon;
|
||||
|
||||
begin
|
||||
CheckToken(tjsSemicolon,';');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestAssign;
|
||||
|
||||
begin
|
||||
CheckToken(tjsAssign,'=');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestGreaterThan;
|
||||
|
||||
begin
|
||||
CheckToken(tjsGT,'>');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestLessThan;
|
||||
|
||||
begin
|
||||
CheckToken(tjsLT,'<');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestPlus;
|
||||
|
||||
begin
|
||||
CheckToken(tjsPlus,'+');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestMinus;
|
||||
|
||||
begin
|
||||
CheckToken(tjsMinus,'-');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestMul;
|
||||
|
||||
begin
|
||||
CheckToken(tjsMul,'*');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestDiv;
|
||||
|
||||
begin
|
||||
CheckToken(tjsDiv,'/');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestEq;
|
||||
|
||||
begin
|
||||
CheckToken(tjsEq,'==');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestGE;
|
||||
|
||||
begin
|
||||
CheckToken(tjsGE,'>=');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestLE;
|
||||
|
||||
begin
|
||||
CheckToken(tjsLE,'<=');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestLSHIFT;
|
||||
|
||||
begin
|
||||
CheckToken(tjsLShift,'<<');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestLSHIFTEQ;
|
||||
|
||||
begin
|
||||
CheckToken(tjsLShiftEq,'<<=');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestMinusEQ;
|
||||
|
||||
begin
|
||||
CheckToken(tjsMinusEq,'-=');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestMinusMinus;
|
||||
|
||||
begin
|
||||
CheckToken(tjsMinusMinus,'--');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestModeq;
|
||||
|
||||
begin
|
||||
CheckToken(tjsModeq,'%=');
|
||||
end;
|
||||
|
||||
|
||||
procedure TTestJSScanner.TestDiveq;
|
||||
|
||||
begin
|
||||
CheckToken(tjsDiveq,'/=');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestXor;
|
||||
begin
|
||||
CheckToken(tjsXOR,'^');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestXoreq;
|
||||
begin
|
||||
CheckToken(tjsXOREQ,'^=');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestNE;
|
||||
|
||||
begin
|
||||
CheckToken(tjsNE,'!=');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestInv;
|
||||
|
||||
begin
|
||||
CheckToken(tjsInv,'~');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestNot;
|
||||
|
||||
begin
|
||||
CheckToken(tjsNot,'!');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestTrue;
|
||||
|
||||
begin
|
||||
CheckToken(tjsTrue,'true');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestFalse;
|
||||
|
||||
begin
|
||||
CheckToken(tjsFalse,'false');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestOREQ;
|
||||
|
||||
begin
|
||||
CheckToken(tjsOREQ,'|=');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestOROR;
|
||||
|
||||
begin
|
||||
CheckToken(tjsOROR,'||');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestPlusEq;
|
||||
|
||||
begin
|
||||
CheckToken(tjsPlusEq,'+=');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestPlusPlus;
|
||||
|
||||
begin
|
||||
CheckToken(tjsPlusPlus,'++');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestURShift;
|
||||
|
||||
begin
|
||||
CheckToken(tjsURSHIFT,'>>>');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestURShiftEq;
|
||||
|
||||
begin
|
||||
CheckToken(tjsURSHIFTEQ,'>>>=');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestRShift;
|
||||
|
||||
begin
|
||||
CheckToken(tjsRSHIFT,'>>');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestRShiftEq;
|
||||
|
||||
begin
|
||||
CheckToken(tjsRSHIFTEQ,'>>=');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestSEq;
|
||||
|
||||
begin
|
||||
CheckToken(tjsSEQ,'===');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestNSE;
|
||||
|
||||
begin
|
||||
CheckToken(tjsSNE,'!==');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestStarEq;
|
||||
|
||||
begin
|
||||
CheckToken(tjsMulEq,'*=');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestBreak;
|
||||
|
||||
begin
|
||||
CheckToken(tjsBreak,'break');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestCase;
|
||||
|
||||
begin
|
||||
CheckToken(tjscase,'case');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestCatch;
|
||||
|
||||
begin
|
||||
CheckToken(tjscatch,'catch');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestContinue;
|
||||
|
||||
begin
|
||||
CheckToken(tjscontinue,'continue');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestDefault;
|
||||
|
||||
begin
|
||||
CheckToken(tjsdefault,'default');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestDelete;
|
||||
|
||||
begin
|
||||
CheckToken(tjsdelete,'delete');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestDO;
|
||||
|
||||
begin
|
||||
CheckToken(tjsdo,'do');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestElse;
|
||||
|
||||
begin
|
||||
CheckToken(tjselse,'else');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestFinally;
|
||||
|
||||
begin
|
||||
CheckToken(tjsfinally,'finally');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestFor;
|
||||
|
||||
begin
|
||||
CheckToken(tjsfor,'for');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestFunction;
|
||||
|
||||
begin
|
||||
CheckToken(tjsfunction,'function');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestIf;
|
||||
|
||||
begin
|
||||
CheckToken(tjsif,'if');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestIn;
|
||||
|
||||
begin
|
||||
CheckToken(tjsin,'in');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestInstanceOf;
|
||||
|
||||
begin
|
||||
CheckToken(tjsinstanceof,'instanceof');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestNew;
|
||||
|
||||
begin
|
||||
CheckToken(tjsnew,'new');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestReturn;
|
||||
|
||||
begin
|
||||
CheckToken(tjsreturn,'return');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestSwitch;
|
||||
|
||||
begin
|
||||
CheckToken(tjsswitch,'switch');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestThis;
|
||||
|
||||
begin
|
||||
CheckToken(tjsThis,'this');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestThrow;
|
||||
|
||||
begin
|
||||
CheckToken(tjsThrow,'throw');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestTry;
|
||||
|
||||
begin
|
||||
CheckToken(tjsTry,'try');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestTypeOf;
|
||||
|
||||
begin
|
||||
CheckToken(tjstypeof,'typeof');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestVar;
|
||||
|
||||
begin
|
||||
CheckToken(tjsvar,'var');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestVoid;
|
||||
|
||||
begin
|
||||
CheckToken(tjsvoid,'void');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestWhile;
|
||||
|
||||
begin
|
||||
CheckToken(tjswhile,'while');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestWith;
|
||||
|
||||
begin
|
||||
CheckToken(tjswith,'with');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.CheckTokens(ASource : String; ATokens : Array of TJSToken);
|
||||
|
||||
Var
|
||||
I : Integer;
|
||||
J : TJSToken;
|
||||
S : String;
|
||||
|
||||
begin
|
||||
CreateScanner(ASource);
|
||||
For I:=Low(ATokens) to High(ATokens) do
|
||||
begin
|
||||
J:=FScanner.FetchToken;
|
||||
S:=GetEnumName(TypeINfo(TJSToken),Ord(ATokens[i]));
|
||||
S:=Format('Source "%s", token %d (%s): expected %s',[ASource,I,FScanner.CurTokenString,S]);
|
||||
AssertEquals(S,ATokens[i],J);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.Test2Words;
|
||||
begin
|
||||
CheckTokens('with do',[tjsWith,tjsDo]);
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.Test3Words;
|
||||
begin
|
||||
CheckTokens('with do for',[tjsWith,tjsDo,tjsFor]);
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestIdentifier;
|
||||
begin
|
||||
CheckToken(tjsIdentifier,'something');
|
||||
AssertEquals('Correct identifier','something',FScanner.CurTokenString);
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestIdentifier2;
|
||||
begin
|
||||
CheckToken(tjsIdentifier,'_something');
|
||||
AssertEquals('Correct identifier','_something',FScanner.CurTokenString);
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestIdentifier3;
|
||||
begin
|
||||
CheckToken(tjsIdentifier,'$');
|
||||
AssertEquals('Correct identifier','$',FScanner.CurTokenString);
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestIdentifier4;
|
||||
begin
|
||||
CheckToken(tjsIdentifier,'_0');
|
||||
AssertEquals('Correct identifier','_0',FScanner.CurTokenString);
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestIdentifier5;
|
||||
begin
|
||||
CheckToken(tjsIdentifier,'$0');
|
||||
AssertEquals('Correct identifier','$0',FScanner.CurTokenString);
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestIdentifierDotIdentifier;
|
||||
begin
|
||||
CheckTokens('something.different',[tjsIdentifier,tjsdot,tjsIdentifier]);
|
||||
// AssertEquals('Correct identifier','something',FScanner.CurTokenString);
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestEOLN;
|
||||
begin
|
||||
CreateScanner('something');
|
||||
FScanner.FetchToken;
|
||||
AssertEquals('Got to end of line after reading single token at EOF',True,FScanner.IsEndOfLine);
|
||||
// AssertEquals('Correct identifier','something',FScanner.CurTokenString);
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestEOLN2;
|
||||
begin
|
||||
CreateScanner('something different');
|
||||
FScanner.FetchToken;
|
||||
AssertEquals('Not yet end of line after reading single token at EOF',False,FScanner.IsEndOfLine);
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestEOLN3;
|
||||
begin
|
||||
CreateScanner('something'#13#10'different');
|
||||
FScanner.FetchToken;
|
||||
AssertEquals('End of line after reading single token',True,FScanner.IsEndOfLine);
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestEOLN4;
|
||||
begin
|
||||
CreateScanner('something'#10'different');
|
||||
FScanner.FetchToken;
|
||||
AssertEquals('End of line after reading first token',True,FScanner.IsEndOfLine);
|
||||
FScanner.FetchToken;
|
||||
AssertEquals('End of line after reading second token',True,FScanner.IsEndOfLine);
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestComment1;
|
||||
begin
|
||||
CreateScanner('// some comment string');
|
||||
AssertEquals('Comment line is skipped',tjsEOF,FScanner.FetchToken);
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestComment2;
|
||||
begin
|
||||
CreateScanner('// some comment string');
|
||||
FScanner.ReturnComments:=True;
|
||||
AssertEquals('Comment line is returned',tjsComment,FScanner.FetchToken);
|
||||
AssertEquals('Comment contents is returned',' some comment string',FScanner.CurTokenString);
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestComment3;
|
||||
begin
|
||||
CreateScanner('/* some comment string */');
|
||||
AssertEquals('Comment line is skipped',tjsEOF,FScanner.FetchToken);
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestComment4;
|
||||
begin
|
||||
CreateScanner('/* some comment string */');
|
||||
FScanner.ReturnComments:=True;
|
||||
AssertEquals('Comment line is returned',tjsComment,FScanner.FetchToken);
|
||||
AssertEquals('Comment contents is returned',' some comment string ',FScanner.CurTokenString);
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestComment5;
|
||||
begin
|
||||
CreateScanner('/* some nested comment // string */');
|
||||
FScanner.ReturnComments:=True;
|
||||
AssertEquals('Comment line is returned',tjsComment,FScanner.FetchToken);
|
||||
AssertEquals('Comment contents is returned',' some nested comment // string ',FScanner.CurTokenString);
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestComment6;
|
||||
begin
|
||||
CreateScanner('// /* some nested comment string */');
|
||||
FScanner.ReturnComments:=True;
|
||||
AssertEquals('Comment line is returned',tjsComment,FScanner.FetchToken);
|
||||
AssertEquals('Comment contents is returned',' /* some nested comment string */',FScanner.CurTokenString);
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TearDown;
|
||||
begin
|
||||
FreeScanner;
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.DoTestFloat(F : Double);
|
||||
|
||||
Var
|
||||
S : String;
|
||||
|
||||
begin
|
||||
Str(F,S);
|
||||
DoTestFloat(F,S);
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.DoTestFloat(F : Double; S : String);
|
||||
|
||||
Var
|
||||
J : TJSToken;
|
||||
C : Double;
|
||||
I : integer;
|
||||
V : String;
|
||||
|
||||
begin
|
||||
CreateScanner(S);
|
||||
J:=FScanner.FetchToken;
|
||||
AssertEquals(S+' is a number',tjsNumber,J);
|
||||
V:=FScanner.CurTokenString;
|
||||
If (Copy(V,1,2)='0x') then
|
||||
begin
|
||||
Flush(output);
|
||||
V:='$'+Copy(V,3,Length(V)-2);
|
||||
C:=StrToInt(V);
|
||||
end
|
||||
else
|
||||
begin
|
||||
Val(V,C,I);
|
||||
If (I<>0) then
|
||||
Fail(FScanner.CurTokenString+' does not contain a float value');
|
||||
end;
|
||||
AssertEquals('Parsed float equals original float',F,C);
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestFloat;
|
||||
|
||||
|
||||
begin
|
||||
DoTestFloat(1.2);
|
||||
DoTestFloat(-1.2);
|
||||
DoTestFloat(0);
|
||||
DoTestFloat(1.2e1);
|
||||
DoTestFloat(-1.2e1);
|
||||
DoTestFloat(0);
|
||||
DoTestFloat(1.2,'1.2');
|
||||
DoTestFloat(-1.2,'-1.2');
|
||||
DoTestFloat(0,'0.0');
|
||||
DoTestFloat(255,'0xff')
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestFloatError;
|
||||
|
||||
begin
|
||||
FErrorSource:='1xz';
|
||||
AssertException('Wrong float',EJSScannerError,@TestErrorSource);
|
||||
end;
|
||||
|
||||
|
||||
procedure TTestJSScanner.DoTestString(S: String);
|
||||
|
||||
Var
|
||||
J : TJSToken;
|
||||
T : String;
|
||||
begin
|
||||
CreateScanner(S);
|
||||
J:=FScanner.FetchToken;
|
||||
AssertEquals(S+' is a string',tjsString,J);
|
||||
If (Length(S)>0) and (S[1] in ['"','''']) then
|
||||
S:=Copy(S,2,Length(S)-2);
|
||||
AssertEquals('Correct string is returned',S,FScanner.CurTokenString);
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestString;
|
||||
|
||||
begin
|
||||
DoTestString('"A string"');
|
||||
DoTestString('""');
|
||||
DoTestString('''''');
|
||||
DoTestString('''A string''');
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestErrorSource;
|
||||
|
||||
begin
|
||||
CreateScanner(FErrorSource);
|
||||
While (FScanner.FetchToken<>tjsEOF) do ;
|
||||
end;
|
||||
|
||||
procedure TTestJSScanner.TestStringError;
|
||||
|
||||
begin
|
||||
FErrorSource:='"A string';
|
||||
AssertException('Unterminated string',EJSScannerError,@TestErrorSource);
|
||||
FErrorSource:='''A string';
|
||||
AssertException('Unterminated string',EJSScannerError,@TestErrorSource);
|
||||
end;
|
||||
|
||||
|
||||
{ TTestLineReader }
|
||||
|
||||
procedure TTestLineReader.CreateReader(AInput: String);
|
||||
begin
|
||||
FData:=TStringStream.Create(AInput);
|
||||
FReader:=TStreamLineReader.Create(FData);
|
||||
end;
|
||||
|
||||
|
||||
procedure TTestLineReader.TearDown;
|
||||
begin
|
||||
FreeAndNil(FReader);
|
||||
FreeAndNil(FData);
|
||||
end;
|
||||
|
||||
procedure TTestLineReader.TestEmpty;
|
||||
begin
|
||||
CreateReader('');
|
||||
AssertEquals('Empty reader returns EOF',True,FReader.IsEOF);
|
||||
AssertEquals('Empty reader returns empty string','',FReader.ReadLine);
|
||||
end;
|
||||
|
||||
procedure TTestLineReader.TestReadLine;
|
||||
begin
|
||||
CreateReader('Something');
|
||||
AssertEquals('Reader with 1 line returns 1 line','Something',FReader.ReadLine);
|
||||
AssertEquals('EOF true after reading line',True,FReader.IsEOF);
|
||||
end;
|
||||
|
||||
procedure TTestLineReader.TestReadLines13;
|
||||
begin
|
||||
CreateReader('Something'#13'else');
|
||||
AssertEquals('Reader with 2 lines returns 1st line','Something',FReader.ReadLine);
|
||||
AssertEquals('Reader with 2 lines returns 2nd line','else',FReader.ReadLine);
|
||||
AssertEquals('EOF true after reading lines',True,FReader.IsEOF);
|
||||
end;
|
||||
|
||||
procedure TTestLineReader.TestReadLines10;
|
||||
begin
|
||||
CreateReader('Something'#10'else');
|
||||
AssertEquals('Reader with 2 lines returns 1st line','Something',FReader.ReadLine);
|
||||
AssertEquals('Reader with 2 lines returns 2nd line','else',FReader.ReadLine);
|
||||
AssertEquals('EOF true after reading lines',True,FReader.IsEOF);
|
||||
end;
|
||||
|
||||
procedure TTestLineReader.TestReadLines1310;
|
||||
begin
|
||||
CreateReader('Something'#13#10'else');
|
||||
AssertEquals('Reader with 2 lines returns 1st line','Something',FReader.ReadLine);
|
||||
AssertEquals('Reader with 2 lines returns 2nd line','else',FReader.ReadLine);
|
||||
AssertEquals('EOF true after reading lines',True,FReader.IsEOF);
|
||||
end;
|
||||
|
||||
procedure TTestLineReader.TestReadLinesEOF13;
|
||||
begin
|
||||
CreateReader('Something'#13);
|
||||
AssertEquals('Reader with 2 lines + CR returns 1st line','Something',FReader.ReadLine);
|
||||
AssertEquals('Reader with 1 lines + CR returns empty 2nd line','',FReader.ReadLine);
|
||||
AssertEquals('EOF true after reading lines',True,FReader.IsEOF);
|
||||
end;
|
||||
|
||||
procedure TTestLineReader.TestReadLinesEOF10;
|
||||
begin
|
||||
CreateReader('Something'#10);
|
||||
AssertEquals('Reader with 2 lines + LF returns 1st line','Something',FReader.ReadLine);
|
||||
AssertEquals('Reader with 1 lines + LF returns empty 2nd line','',FReader.ReadLine);
|
||||
AssertEquals('EOF true after reading lines',True,FReader.IsEOF);
|
||||
end;
|
||||
|
||||
procedure TTestLineReader.TestReadLinesEOF1310;
|
||||
begin
|
||||
CreateReader('Something'#13#10);
|
||||
AssertEquals('Reader with 2 lines + CRLF returns 1st line','Something',FReader.ReadLine);
|
||||
AssertEquals('Reader with 1 lines + CRLF returns empty 2nd line','',FReader.ReadLine);
|
||||
AssertEquals('EOF true after reading lines',True,FReader.IsEOF);
|
||||
end;
|
||||
|
||||
procedure TTestLineReader.TestReadEmptyLines101010;
|
||||
|
||||
begin
|
||||
CreateReader('Something'#10#10#10);
|
||||
AssertEquals('Reader with 1 line + LFLFLF returns 1st line','Something',FReader.ReadLine);
|
||||
AssertEquals('EOF false after reading line 1',False,FReader.IsEOF);
|
||||
AssertEquals('Reader with 1 line + LFLFLF returns empty 2nd line','',FReader.ReadLine);
|
||||
AssertEquals('EOF false after reading line 2',False,FReader.IsEOF);
|
||||
AssertEquals('Reader with 1 line + LFLFLF returns empty 3nd line','',FReader.ReadLine);
|
||||
AssertEquals('EOF true after reading lines',True,FReader.IsEOF);
|
||||
end;
|
||||
|
||||
initialization
|
||||
|
||||
RegisterTests([TTestLineReader,TTestJSScanner]);
|
||||
end.
|
||||
|
||||
BIN
packages/fcl-js/tests/testjs.ico
Normal file
BIN
packages/fcl-js/tests/testjs.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 134 KiB |
261
packages/fcl-js/tests/testjs.lpi
Normal file
261
packages/fcl-js/tests/testjs.lpi
Normal file
@ -0,0 +1,261 @@
|
||||
<?xml version="1.0"?>
|
||||
<CONFIG>
|
||||
<ProjectOptions>
|
||||
<Version Value="7"/>
|
||||
<General>
|
||||
<MainUnit Value="0"/>
|
||||
<TargetFileExt Value=""/>
|
||||
<Icon Value="0"/>
|
||||
<UseXPManifest Value="True"/>
|
||||
<ActiveEditorIndexAtStart Value="1"/>
|
||||
</General>
|
||||
<VersionInfo>
|
||||
<ProjectVersion Value=""/>
|
||||
<Language Value=""/>
|
||||
<CharSet Value=""/>
|
||||
</VersionInfo>
|
||||
<PublishOptions>
|
||||
<Version Value="2"/>
|
||||
<IgnoreBinaries Value="False"/>
|
||||
<IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
|
||||
<ExcludeFileFilter Value="*.(bak|ppu|ppw|o|so);*~;backup"/>
|
||||
</PublishOptions>
|
||||
<RunParams>
|
||||
<local>
|
||||
<FormatVersion Value="1"/>
|
||||
<CommandLineParams Value="-a --format=plain"/>
|
||||
<LaunchingApplication PathPlusParams="/usr/X11R6/bin/xterm -T 'Lazarus Run Output' -e $(LazarusDir)/tools/runwait.sh $(TargetCmdLine)"/>
|
||||
</local>
|
||||
</RunParams>
|
||||
<RequiredPackages Count="2">
|
||||
<Item1>
|
||||
<PackageName Value="FPCUnitConsoleRunner"/>
|
||||
</Item1>
|
||||
<Item2>
|
||||
<PackageName Value="FCL"/>
|
||||
</Item2>
|
||||
</RequiredPackages>
|
||||
<Units Count="7">
|
||||
<Unit0>
|
||||
<Filename Value="testjs.lpr"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="testjs"/>
|
||||
<CursorPos X="11" Y="7"/>
|
||||
<TopLine Value="1"/>
|
||||
<EditorIndex Value="0"/>
|
||||
<UsageCount Value="201"/>
|
||||
<Loaded Value="True"/>
|
||||
</Unit0>
|
||||
<Unit1>
|
||||
<Filename Value="tcscanner.pp"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="tcscanner"/>
|
||||
<CursorPos X="27" Y="427"/>
|
||||
<TopLine Value="416"/>
|
||||
<EditorIndex Value="2"/>
|
||||
<UsageCount Value="201"/>
|
||||
<Loaded Value="True"/>
|
||||
</Unit1>
|
||||
<Unit2>
|
||||
<Filename Value="../src/jsbase.pp"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="jsbase"/>
|
||||
<CursorPos X="1" Y="153"/>
|
||||
<TopLine Value="132"/>
|
||||
<EditorIndex Value="1"/>
|
||||
<UsageCount Value="196"/>
|
||||
<Loaded Value="True"/>
|
||||
</Unit2>
|
||||
<Unit3>
|
||||
<Filename Value="../src/jsparser.pp"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="jsparser"/>
|
||||
<CursorPos X="1" Y="1"/>
|
||||
<TopLine Value="1"/>
|
||||
<UsageCount Value="201"/>
|
||||
</Unit3>
|
||||
<Unit4>
|
||||
<Filename Value="../src/jsscanner.pp"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="JSScanner"/>
|
||||
<CursorPos X="1" Y="1"/>
|
||||
<TopLine Value="1"/>
|
||||
<UsageCount Value="201"/>
|
||||
</Unit4>
|
||||
<Unit5>
|
||||
<Filename Value="../src/jstree.pp"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="jstree"/>
|
||||
<CursorPos X="1" Y="1"/>
|
||||
<TopLine Value="1"/>
|
||||
<UsageCount Value="200"/>
|
||||
</Unit5>
|
||||
<Unit6>
|
||||
<Filename Value="tcparser.pp"/>
|
||||
<IsPartOfProject Value="True"/>
|
||||
<UnitName Value="tcparser"/>
|
||||
<CursorPos X="3" Y="2059"/>
|
||||
<TopLine Value="2051"/>
|
||||
<EditorIndex Value="4"/>
|
||||
<UsageCount Value="97"/>
|
||||
<Loaded Value="True"/>
|
||||
</Unit6>
|
||||
</Units>
|
||||
<JumpHistory Count="30" HistoryIndex="29">
|
||||
<Position1>
|
||||
<Filename Value="tcparser.pp"/>
|
||||
<Caret Line="1752" Column="1" TopLine="1730"/>
|
||||
</Position1>
|
||||
<Position2>
|
||||
<Filename Value="tcparser.pp"/>
|
||||
<Caret Line="1767" Column="32" TopLine="1733"/>
|
||||
</Position2>
|
||||
<Position3>
|
||||
<Filename Value="tcparser.pp"/>
|
||||
<Caret Line="1790" Column="30" TopLine="1766"/>
|
||||
</Position3>
|
||||
<Position4>
|
||||
<Filename Value="tcparser.pp"/>
|
||||
<Caret Line="1763" Column="26" TopLine="1736"/>
|
||||
</Position4>
|
||||
<Position5>
|
||||
<Filename Value="tcparser.pp"/>
|
||||
<Caret Line="1791" Column="1" TopLine="1758"/>
|
||||
</Position5>
|
||||
<Position6>
|
||||
<Filename Value="tcparser.pp"/>
|
||||
<Caret Line="114" Column="30" TopLine="93"/>
|
||||
</Position6>
|
||||
<Position7>
|
||||
<Filename Value="tcparser.pp"/>
|
||||
<Caret Line="1806" Column="23" TopLine="1798"/>
|
||||
</Position7>
|
||||
<Position8>
|
||||
<Filename Value="tcparser.pp"/>
|
||||
<Caret Line="1828" Column="3" TopLine="1819"/>
|
||||
</Position8>
|
||||
<Position9>
|
||||
<Filename Value="../../../../source/fcl-js/jsparser.pp"/>
|
||||
<Caret Line="515" Column="28" TopLine="507"/>
|
||||
</Position9>
|
||||
<Position10>
|
||||
<Filename Value="tcparser.pp"/>
|
||||
<Caret Line="1824" Column="24" TopLine="1803"/>
|
||||
</Position10>
|
||||
<Position11>
|
||||
<Filename Value="tcparser.pp"/>
|
||||
<Caret Line="1828" Column="17" TopLine="1803"/>
|
||||
</Position11>
|
||||
<Position12>
|
||||
<Filename Value="tcparser.pp"/>
|
||||
<Caret Line="1849" Column="34" TopLine="1820"/>
|
||||
</Position12>
|
||||
<Position13>
|
||||
<Filename Value="tcparser.pp"/>
|
||||
<Caret Line="118" Column="27" TopLine="96"/>
|
||||
</Position13>
|
||||
<Position14>
|
||||
<Filename Value="tcparser.pp"/>
|
||||
<Caret Line="1900" Column="29" TopLine="1888"/>
|
||||
</Position14>
|
||||
<Position15>
|
||||
<Filename Value="tcparser.pp"/>
|
||||
<Caret Line="1898" Column="12" TopLine="1877"/>
|
||||
</Position15>
|
||||
<Position16>
|
||||
<Filename Value="tcparser.pp"/>
|
||||
<Caret Line="1904" Column="80" TopLine="1883"/>
|
||||
</Position16>
|
||||
<Position17>
|
||||
<Filename Value="tcparser.pp"/>
|
||||
<Caret Line="1914" Column="29" TopLine="1883"/>
|
||||
</Position17>
|
||||
<Position18>
|
||||
<Filename Value="tcparser.pp"/>
|
||||
<Caret Line="1948" Column="18" TopLine="1914"/>
|
||||
</Position18>
|
||||
<Position19>
|
||||
<Filename Value="tcparser.pp"/>
|
||||
<Caret Line="20" Column="1" TopLine="1"/>
|
||||
</Position19>
|
||||
<Position20>
|
||||
<Filename Value="tcparser.pp"/>
|
||||
<Caret Line="2165" Column="1" TopLine="2124"/>
|
||||
</Position20>
|
||||
<Position21>
|
||||
<Filename Value="tcparser.pp"/>
|
||||
<Caret Line="121" Column="27" TopLine="99"/>
|
||||
</Position21>
|
||||
<Position22>
|
||||
<Filename Value="tcparser.pp"/>
|
||||
<Caret Line="1969" Column="3" TopLine="1960"/>
|
||||
</Position22>
|
||||
<Position23>
|
||||
<Filename Value="tcparser.pp"/>
|
||||
<Caret Line="1971" Column="46" TopLine="1950"/>
|
||||
</Position23>
|
||||
<Position24>
|
||||
<Filename Value="tcparser.pp"/>
|
||||
<Caret Line="1986" Column="14" TopLine="1961"/>
|
||||
</Position24>
|
||||
<Position25>
|
||||
<Filename Value="tcparser.pp"/>
|
||||
<Caret Line="1993" Column="33" TopLine="1960"/>
|
||||
</Position25>
|
||||
<Position26>
|
||||
<Filename Value="../../../../source/fcl-js/jsparser.pp"/>
|
||||
<Caret Line="1702" Column="24" TopLine="1685"/>
|
||||
</Position26>
|
||||
<Position27>
|
||||
<Filename Value="tcparser.pp"/>
|
||||
<Caret Line="124" Column="25" TopLine="100"/>
|
||||
</Position27>
|
||||
<Position28>
|
||||
<Filename Value="tcparser.pp"/>
|
||||
<Caret Line="2038" Column="10" TopLine="2035"/>
|
||||
</Position28>
|
||||
<Position29>
|
||||
<Filename Value="tcparser.pp"/>
|
||||
<Caret Line="2075" Column="56" TopLine="2051"/>
|
||||
</Position29>
|
||||
<Position30>
|
||||
<Filename Value="../../../../source/fcl-js/jsparser.pp"/>
|
||||
<Caret Line="1747" Column="29" TopLine="1740"/>
|
||||
</Position30>
|
||||
</JumpHistory>
|
||||
</ProjectOptions>
|
||||
<CompilerOptions>
|
||||
<Version Value="8"/>
|
||||
<SearchPaths>
|
||||
<IncludeFiles Value="$(ProjOutDir)/"/>
|
||||
<OtherUnitFiles Value="/home/michael/source/fcl-js/;../"/>
|
||||
</SearchPaths>
|
||||
<CodeGeneration>
|
||||
<Optimizations>
|
||||
<OptimizationLevel Value="0"/>
|
||||
</Optimizations>
|
||||
</CodeGeneration>
|
||||
<Other>
|
||||
<CompilerPath Value="$(CompPath)"/>
|
||||
</Other>
|
||||
</CompilerOptions>
|
||||
<Debugging>
|
||||
<BreakPoints Count="1">
|
||||
<Item1>
|
||||
<Source Value="../jsscanner.pp"/>
|
||||
<Line Value="717"/>
|
||||
</Item1>
|
||||
</BreakPoints>
|
||||
<Exceptions Count="3">
|
||||
<Item1>
|
||||
<Name Value="EAbort"/>
|
||||
</Item1>
|
||||
<Item2>
|
||||
<Name Value="ECodetoolError"/>
|
||||
</Item2>
|
||||
<Item3>
|
||||
<Name Value="EFOpenError"/>
|
||||
</Item3>
|
||||
</Exceptions>
|
||||
</Debugging>
|
||||
</CONFIG>
|
||||
29
packages/fcl-js/tests/testjs.lpr
Normal file
29
packages/fcl-js/tests/testjs.lpr
Normal file
@ -0,0 +1,29 @@
|
||||
program testjs;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
uses
|
||||
Classes, consoletestrunner, tcscanner, jsparser, jsscanner, jstree, jsbase,
|
||||
tcparser;
|
||||
|
||||
type
|
||||
|
||||
{ TLazTestRunner }
|
||||
|
||||
TMyTestRunner = class(TTestRunner)
|
||||
protected
|
||||
// override the protected methods of TTestRunner to customize its behavior
|
||||
end;
|
||||
|
||||
var
|
||||
Application: TMyTestRunner;
|
||||
|
||||
{$IFDEF WINDOWS}{$R testjs.rc}{$ENDIF}
|
||||
|
||||
begin
|
||||
Application := TMyTestRunner.Create(nil);
|
||||
Application.Initialize;
|
||||
Application.Title := 'FPCUnit Console test runner';
|
||||
Application.Run;
|
||||
Application.Free;
|
||||
end.
|
||||
17
packages/fcl-js/tests/testjs.manifest
Normal file
17
packages/fcl-js/tests/testjs.manifest
Normal file
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
|
||||
<assemblyIdentity version="1.0.0.0" processorArchitecture="*" name="CompanyName.ProductName.YourApp" type="win32"/>
|
||||
<description>Your application description here.</description>
|
||||
<dependency>
|
||||
<dependentAssembly>
|
||||
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" processorArchitecture="*" publicKeyToken="6595b64144ccf1df" language="*"/>
|
||||
</dependentAssembly>
|
||||
</dependency>
|
||||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||
<security>
|
||||
<requestedPrivileges>
|
||||
<requestedExecutionLevel level="asInvoker" uiAccess="false"/>
|
||||
</requestedPrivileges>
|
||||
</security>
|
||||
</trustInfo>
|
||||
</assembly>
|
||||
1
packages/fcl-js/tests/testjs.rc
Normal file
1
packages/fcl-js/tests/testjs.rc
Normal file
@ -0,0 +1 @@
|
||||
MAINICON ICON "testjs.ico"
|
||||
Loading…
Reference in New Issue
Block a user