pax_c.pas
来自「Delphi脚本控件」· PAS 代码 · 共 2,854 行 · 第 1/5 页
PAS
2,854 行
////////////////////////////////////////////////////////////////////////////
// PAXScript Interpreter
// Author: Alexander Baranovsky (ab@cable.netlux.org)
// ========================================================================
// Copyright (c) Alexander Baranovsky, 2003-2005. All rights reserved.
// Code Version: 3.0
// ========================================================================
// Unit: PAX_C.pas
// ========================================================================
////////////////////////////////////////////////////////////////////////////
{$I PaxScript.def}
unit PAX_C;
interface
uses
SysUtils, Classes,
BASE_CONSTS,
BASE_SYS, BASE_SCANNER, BASE_PARSER, BASE_SCRIPTER, BASE_EXTERN, BASE_CLASS;
const
SP_INC = -1001;
SP_DEC = -1002;
SP_PLUS_ASSIGN = -1003;
SP_MINUS_ASSIGN = -1004;
SP_MULT_ASSIGN = -1005;
SP_DIV_ASSIGN = -1006;
SP_MOD_ASSIGN = -1007;
SP_LEFT_SHIFT_ASSIGN = -1008;
SP_RIGHT_SHIFT_ASSIGN = -1009;
SP_UNSIGNED_RIGHT_SHIFT_ASSIGN = -1011;
SP_BITWISE_AND = -1012;
SP_BITWISE_OR = -1013;
SP_BITWISE_XOR = -1014;
SP_LOGICAL_AND = -1015;
SP_LOGICAL_OR = -1016;
SP_BITWISE_NOT = -1017;
SP_LOGICAL_NOT = -1018;
SP_COND = -1019;
SP_OR_ASSIGN = -1020;
SP_AND_ASSIGN = -1021;
type
TSCScanner = class(TPAXScanner)
public
procedure ReadToken; override;
end;
TPAXCParser = class(TPAXParser)
private
ConstIds: TPAXIds;
procedure ScanFIELD;
public
constructor Create; override;
destructor Destroy; override;
procedure Reset; override;
procedure Call_SCANNER; override;
function IsBaseType(const S: String): Boolean; override;
function Parse_EvalExpression: Integer; override;
function Parse_ArgumentExpression: Integer; override;
function Parse_PrimaryExpression: Integer;
function Parse_ObjectLiteral: Integer;
function Parse_MemberExpression(ID: Integer; IsConstructor: boolean = false): Integer;
function Parse_NewExpression: Integer;
function Parse_LeftHandSideExpression: Integer;
function Parse_PostfixExpression(Left: Integer): Integer;
function Parse_UnaryExpression(Left: Integer): Integer;
function Parse_MultiplicativeExpression(Left: Integer): Integer;
function Parse_AdditiveExpression(Left: Integer): Integer;
function Parse_ShiftExpression(Left: Integer): Integer;
function Parse_RelationalExpression(Left: Integer): Integer;
function Parse_EqualityExpression(Left: Integer): Integer;
function Parse_BitwiseANDExpression(Left: Integer): Integer;
function Parse_BitwiseXORExpression(Left: Integer): Integer;
function Parse_BitwiseORExpression(Left: Integer): Integer;
function Parse_LogicalANDExpression(Left: Integer): Integer;
function Parse_LogicalORExpression(Left: Integer): Integer;
function Parse_ConditionalExpression(Left: Integer): Integer;
function Parse_AssignmentExpression: Integer;
function Parse_Expression: Integer;
function Parse_ModifierList: TPAXModifierList;
procedure Parse_Statement;
procedure Parse_Block;
procedure Parse_IfStmt;
procedure Parse_NamespaceStmt(ml: TPAXModifierList);
procedure Parse_FunctionStmt(ml: TPAXModifierList;
T: Integer = typeVARIANT;
const DllName: String = '');
procedure Parse_ReturnStmt;
procedure Parse_HaltStmt;
procedure Parse_VarStmt(IsField: Boolean; ml: TPAXModifierList;
T: Integer = 0;
IsLoopVar: Boolean = false);
function Parse_VariableDeclaration(IsField: Boolean;
ml: TPAXModifierList; T: Integer;
IsLoopVar: Boolean = false): Integer;
function Parse_ClassStmt(ClassML: TPAXModifierList; ck: TPAXClassKind): Integer;
function Parse_EnumStmt: Integer;
procedure Parse_ExpressionStmt;
procedure Parse_WhileStmt;
procedure Parse_DoStmt;
procedure Parse_ForStmt;
procedure Parse_ContinueStmt;
procedure Parse_BreakStmt;
procedure Parse_SwitchStmt;
procedure Parse_WithStmt;
procedure Parse_ThrowStmt;
procedure Parse_TryStmt;
procedure Parse_StmtList; override;
procedure Parse_SourceElements;
procedure Parse_Program; override;
end;
implementation
procedure TSCScanner.ReadToken;
begin
inherited;
repeat
if BuffToken.Text <> '' then
begin
Token := BuffToken;
BuffToken.Text := '';
Exit;
end;
GetNextChar;
Token.TokenClass := tcNone;
case c of
#8, #9, #10, #13, #32: ScanWhiteSpace;
#255: ScanEOF;
'0'..'9': ScanDigits;
'$': ScanHexDigits;
'A'..'Z', 'a'..'z', '_':
begin
ScanIdentifier;
if StrEql(Token.Text, 'in') then
begin
Token.TokenClass := tcSpecial;
Token.ID := OP_IN;
end
else if StrEql(Token.Text, 'instanceof') then
begin
Token.TokenClass := tcSpecial;
Token.ID := OP_INSTANCEOF;
end
else if StrEql(Token.Text, 'delete') then
begin
Token.TokenClass := tcSpecial;
Token.ID := OP_DESTROY_OBJECT;
end;
end;
'+':
begin
ScanPlus;
case LA(1) of
'+':
begin
GetNextChar;
Token.Text := '++';
Token.ID := SP_INC;
end;
'=':
begin
GetNextChar;
Token.Text := '+=';
Token.ID := SP_PLUS_ASSIGN;
end;
end;
end;
'-':
begin
ScanMinus;
case LA(1) of
'-':
begin
GetNextChar;
Token.Text := '--';
Token.ID := SP_DEC;
end;
'=':
begin
GetNextChar;
Token.Text := '-=';
Token.ID := SP_MINUS_ASSIGN;
end;
end;
end;
'*':
begin
ScanMult;
if LA(1) = '=' then
begin
GetNextChar;
Token.Text := '*=';
Token.ID := SP_MULT_ASSIGN;
end;
end;
'/':
begin
if LA(1) = '*' then
begin
repeat
GetNextChar;
if c in [#10,#13] then
begin
IncLineNumber;
PosNumber := -1;
if c = #13 then
GetNextChar;
end;
until ((LA(1) = '*') and (LA(2) = '/')) or (LA(1) = #255);
GetNextChar;
GetNextChar;
Continue;
end
else if LA(1) = '/' then
begin
repeat
GetNextChar;
until LA(1) in [#13, #10];
Continue;
end;
ScanDiv;
if LA(1) = '=' then
begin
GetNextChar;
Token.Text := '/=';
Token.ID := SP_DIV_ASSIGN;
end;
end;
'=':
begin
ScanEQ;
Token.ID := OP_ASSIGN;
if LA(1) = '=' then
begin
GetNextChar;
Token.Text := '==';
Token.ID := OP_EQ;
end;
end;
'>':
begin
ScanGT;
case LA(1) of
'=':
begin
GetNextChar;
Token.Text := '>=';
Token.ID := OP_GE;
end;
'>':
begin
GetNextChar;
Token.Text := '>>';
Token.ID := OP_RIGHT_SHIFT;
case LA(1) of
'=':
begin
GetNextChar;
Token.Text := '>>=';
Token.ID := SP_RIGHT_SHIFT_ASSIGN;
end;
'>':
begin
GetNextChar;
Token.Text := '>>>';
Token.ID := OP_UNSIGNED_RIGHT_SHIFT;
if LA(1) = '=' then
begin
GetNextChar;
Token.Text := '>>>=';
Token.ID := SP_UNSIGNED_RIGHT_SHIFT_ASSIGN;
end;
end;
end;
end;
end;
end;
'<':
case ScannerState of
scanText:
begin
if LA(1) = '?' then
begin
GetNextChar;
GetNextChar;
ScanIdentifier;
if not StrEql('pax', Trim(Token.Text)) then
raise TPAXScriptFailure.Create(errIllegalCharacter);
ScannerState := scanProg;
Continue;
end
else if LA(1) = '%' then
begin
GetNextChar;
ScannerState := scanProg;
if LA(1) = '=' then
begin
GetNextChar;
BuffToken.Text := 'print';
end;
Continue;
end
else if LA(1) in ['a'..'z','A'..'Z'] then
ScanHtmlString(c)
else
raise TPAXScriptFailure.Create(errIllegalCharacter);
end;
scanProg:
begin
ScanLT;
case LA(1) of
'=':
begin
GetNextChar;
Token.Text := '<=';
Token.ID := OP_LE;
end;
'<':
begin
GetNextChar;
Token.Text := '<<';
Token.ID := OP_LEFT_SHIFT;
if LA(1) = '=' then
begin
GetNextChar;
Token.Text := '<<=';
Token.ID := SP_LEFT_SHIFT_ASSIGN;
end;
end;
end;
end;
end;
':': ScanColon;
'!':
begin
Token.Text := c;
Token.ID := SP_LOGICAL_NOT;
Token.TokenClass := tcSpecial;
if LA(1) = '=' then
begin
GetNextChar;
Token.Text := '!=';
Token.ID := OP_NE;
end
end;
'%':
case ScannerState of
scanText:
raise TPAXScriptFailure.Create(errIllegalCharacter);
scanProg:
if LA(1) = '>' then
begin
ScannerState := scanText;
GetNextChar;
ScanHtmlString('');
end
else
begin
ScanMod;
if LA(1) = '=' then
begin
GetNextChar;
Token.Text := '%=';
Token.ID := SP_MOD_ASSIGN;
end;
end;
end;
'~':
begin
Token.Text := c;
Token.ID := SP_BITWISE_NOT;
Token.TokenClass := tcSpecial;
end;
'?':
begin
case ScannerState of
ScanText:
raise TPAXScriptFailure.Create(errIllegalCharacter);
ScanProg:
begin
if LA(1) = '>' then
begin
ScannerState := scanText;
GetNextChar;
ScanHtmlString('');
end
else
begin
Token.Text := c;
Token.ID := SP_COND;
Token.TokenClass := tcSpecial;
end;
end;
end;
end;
'|':
begin
Token.Text := c;
Token.ID := SP_BITWISE_OR;
Token.TokenClass := tcSpecial;
if LA(1) = '|' then
begin
GetNextChar;
Token.Text := '||';
Token.ID := SP_LOGICAL_OR;
end
else if LA(1) = '=' then
begin
GetNextChar;
Token.Text := '|=';
Token.ID := SP_OR_ASSIGN;
end;
end;
'&':
begin
Token.Text := c;
Token.ID := SP_BITWISE_AND;
Token.TokenClass := tcSpecial;
if LA(1) = '&' then
begin
GetNextChar;
Token.Text := '&&';
Token.ID := SP_LOGICAL_AND;
end
else if LA(1) = '=' then
begin
GetNextChar;
Token.Text := '|=';
Token.ID := SP_AND_ASSIGN;
end;
end;
'#':
if LookForward then
begin
repeat
GetNextChar;
until LA(1) in [#13, #10];
continue;
end
else
begin
ScanCondDir('#', ['a'..'z','A'..'Z','_','0'..'9']);
continue;
end;
';': ScanSemiColon;
'(': ScanLeftRoundBracket;
')': ScanRightRoundBracket;
'[': ScanLeftBracket;
']': ScanRightBracket;
'{': ScanLeftBrace;
'}': ScanRightBrace;
',': ScanComma;
'.': ScanPoint;
'''': ScanString('''');
'"': ScanString('"');
else
raise TPAXScriptFailure.Create(errIllegalCharacter);
end;
if Token.TokenClass <> tcNone then
Exit;
until false;
end;
constructor TPAXCParser.Create;
begin
ConstIds := TPAXIds.Create(false);
inherited;
Scanner := TSCScanner.Create(Self);
UpCase := false;
with Keywords do
begin
Add('base');
Add('break');
Add('bool');
Add('byte');
Add('case');
Add('catch');
Add('cdecl');
Add('class');
Add('const');
Add('continue');
Add('delete');
Add('do');
Add('double');
Add('else');
Add('extern');
Add('false');
Add('finally');
Add('for');
Add('function');
Add('get');
Add('goto');
Add('enum');
Add('if');
Add('in');
Add('int');
Add('long');
Add('float');
Add('decimal');
Add('namespace');
Add('new');
Add('operator');
Add('override');
Add('out');
Add('pascal');
Add('public');
Add('private');
Add('ref');
Add('reduced');
Add('register');
Add('return');
Add('safecall');
Add('sbyte');
Add('set');
Add('short');
Add('static');
Add('stdcall');
Add('string');
Add('structure');
Add('switch');
// Add('THIS');
Add('throw');
Add('true');
Add('try');
Add('typeof');
Add('var');
Add('virtual');
Add('void');
Add('ushort');
Add('using');
Add('while');
Add('with');
Add('print');
Add('println');
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?