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.