{
Этот исходный текст является частью Продвинутого векторного транслятора.
Copyright © 2017 Малик Разработчик
Это свободная программа: вы можете перераспространять её и/или
изменять её на условиях Стандартной общественной лицензии GNU в том виде,
в каком она была опубликована Фондом свободного программного обеспечения;
либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.
Эта программа распространяется в надежде, что она может быть полезна,
но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЁННЫХ ЦЕЛЕЙ. Подробнее см. в Стандартной
общественной лицензии GNU.
Вы должны были получить копию Стандартной общественной лицензии GNU
вместе с этой программой. Если это не так, см.
<http://www.gnu.org/licenses/>.
}
unit BuildNms;
{$MODE DELPHI,EXTENDEDSYNTAX ON}
interface
uses
Lang, TranIntf, TranType, TranProg, BuildLex;
{$ASMMODE INTEL,CALLING REGISTER,INLINE ON,GOTO ON}
{$H+,I-,J-,M-,Q-,R-,T-}
type
TranslatorNamespacesBuilder = class;
TranslatorLocalConstantInt = class;
TranslatorLocalConstantLong = class;
TranslatorLocalConstantReal = class;
TranslatorLocalConstantUltra = class;
TranslatorLocalConstantXVector = class;
TranslatorNamespacesBuilder = class(RefCountInterfacedObject, BuilderOfNamespaces)
public
const EXTENSION_SSE3 = 0;
const EXTENSION_SSSE3 = 1;
const EXTENSION_SSE4_1 = 2;
const NAMESPACE_SYSTEM = 'System';
const STRUCTURE_POINTER = 'Pointer';
const EXCEPTION_THROWABLE = 'Throwable';
const EXCEPTION_EXCEPTION = 'Exception';
const FUNCTION_INITIALIZATION = 'initialization';
const FUNCTION_FINALIZATION = 'finalization';
const FUNCTION_NEW_STRUCT = 'new.struct';
const FUNCTION_NEW_ARRAY = 'new.array';
const FUNCTION_DISPOSE = 'dispose';
const FUNCTION_MAIN = 'main';
class function pack4IntUS(const value: ultra): long;
public
constructor create(operandSize, extension: int);
procedure clear(); virtual;
procedure addLexer(lexemes: Lexer); virtual;
procedure buildNamespaces(); virtual;
function getNamespacesCount(): int; virtual;
function getNamespace(index: int): Namespace; virtual;
function getSystemNamespace(): Namespace; virtual;
function getEntryPoint(): GlobalFunction; virtual;
function findNamespace(const name: UnicodeString): Namespace; virtual;
strict private
fldOperandSize: int;
fldExtension: int;
fldStayPosition: int;
initTypesCount: int;
lexersCount: int;
namespacesCount: int;
typesCount: int;
lexers: Lexer_Array1d;
namespaces: Namespace_Array1d;
types: TypeDescriptor_Array1d;
systemNamespace: Namespace;
entryPoint: GlobalFunction;
procedure addNamespace(space: Namespace);
procedure parseFields(structure: TypeStructure; lexemes: Lexer);
function parseEntry(where: Namespace; lexemes: Lexer; position: int): int;
function parseConstant(where: Namespace; lexemes: Lexer; position: int;
epublic: boolean): int;
function parseException(where: Namespace; lexemes: Lexer; position: int;
epublic: boolean): int;
function parseStructure(where: Namespace; lexemes: Lexer; position: int;
epublic: boolean): int;
function parseVarOrFunc(where: Namespace; lexemes: Lexer; position: int;
epublic: boolean): int;
function parseArguments(where: Namespace; lexemes: Lexer; position: int;
destination: TypeFunction): int;
function parseConstElem(where: Namespace; lexemes: Lexer; position: int): GlobalConstant;
function parseConstPref(where: Namespace; lexemes: Lexer; position: int): GlobalConstant;
function parseConstMult(where: Namespace; lexemes: Lexer; position: int): GlobalConstant;
function parseConstAdd(where: Namespace; lexemes: Lexer; position: int): GlobalConstant;
function parseConstShift(where: Namespace; lexemes: Lexer; position: int): GlobalConstant;
function parseConstRel(where: Namespace; lexemes: Lexer; position: int): GlobalConstant;
function parseConstEqual(where: Namespace; lexemes: Lexer; position: int): GlobalConstant;
function parseConstBAnd(where: Namespace; lexemes: Lexer; position: int): GlobalConstant;
function parseConstBXor(where: Namespace; lexemes: Lexer; position: int): GlobalConstant;
function parseConstBOr(where: Namespace; lexemes: Lexer; position: int): GlobalConstant;
function parseConstLAnd(where: Namespace; lexemes: Lexer; position: int): GlobalConstant;
function parseConstLOr(where: Namespace; lexemes: Lexer; position: int): GlobalConstant;
function parseConstCond(where: Namespace; lexemes: Lexer; position: int): GlobalConstant;
strict private
fldTypVoid: TypePrimitive;
fldTypBoolean: TypePrimitive;
fldTypChar: TypePrimitive;
fldTypByte: TypePrimitive;
fldTypShort: TypePrimitive;
fldTypInt: TypePrimitive;
fldTypLong: TypePrimitive;
fldTypUltra: TypePrimitive;
fldTypFloat: TypePrimitive;
fldTypDouble: TypePrimitive;
fldTypReal: TypePrimitive;
fldTypXVector: TypePrimitive;
protected
property stayPosition: int read fldStayPosition write fldStayPosition;
property operandSize: int read fldOperandSize;
property extension: int read fldExtension;
property typeVoid: TypePrimitive read fldTypVoid;
property typeBoolean: TypePrimitive read fldTypBoolean;
property typeChar: TypePrimitive read fldTypChar;
property typeByte: TypePrimitive read fldTypByte;
property typeShort: TypePrimitive read fldTypShort;
property typeInt: TypePrimitive read fldTypInt;
property typeLong: TypePrimitive read fldTypLong;
property typeUltra: TypePrimitive read fldTypUltra;
property typeFloat: TypePrimitive read fldTypFloat;
property typeDouble: TypePrimitive read fldTypDouble;
property typeReal: TypePrimitive read fldTypReal;
property typeXVector: TypePrimitive read fldTypXVector;
function possibleAssign(dstTypeKind: int; constant: GlobalConstant): boolean; virtual;
function skipCurlyBrackets(lexemes: Lexer; position: int): int; virtual;
function skipParenthesis(lexemes: Lexer; position: int): int; virtual;
function getCommonTypeKind(kind1, kind2: int): int; virtual;
function castConstTo(newTypeKind: int; constant: GlobalConstant): GlobalConstant; virtual;
function tryParseType(where: Namespace; position: int): TypeDescriptor; virtual;
function parseConst(where: Namespace; position: int): GlobalConstant; virtual;
function parseType(where: Namespace; position: int): TypeDescriptor; virtual;
function getCanonicalType(theType: TypeDescriptor): TypeDescriptor; virtual;
end;
TranslatorLocalConstantInt = class(TranslatorGlobalConstantInt)
public
constructor create(constType: TypeDescriptor; const constValue: boolean); overload;
constructor create(constType: TypeDescriptor; const constValue: int); overload;
end;
TranslatorLocalConstantLong = class(TranslatorGlobalConstantLong)
public
constructor create(constType: TypeDescriptor; const constValue: int64);
end;
TranslatorLocalConstantReal = class(TranslatorGlobalConstantReal)
public
constructor create(constType: TypeDescriptor; const constValue: real);
end;
TranslatorLocalConstantUltra = class(TranslatorGlobalConstantUltra)
public
constructor create(constType: TypeDescriptor; const constValue: ultra);
end;
TranslatorLocalConstantXVector = class(TranslatorGlobalConstantXVector)
public
constructor create(constType: TypeDescriptor; const constValue: xvector);
end;
resourcestring
msgExpressionError = 'Ошибка в выражении.';
msgExpectedDataType = 'Ожидается тип данных.';
msgExpectedConstant = 'Ожидается константа.';
msgExpectedException = 'Ожидается исключение.';
msgExpectedStructure = 'Ожидается структура.';
msgExpectedDataTypeCompound = 'Ожидается идентификатор составного типа данных.';
msgExpectedComma = 'Ожидается запятая (",").';
msgExpectedPeriod = 'Ожидается точка (".").';
msgExpectedAssign = 'Ожидается знак равенства ("=").';
msgExpectedColon = 'Ожидается двоеточие (":").';
msgExpectedSemicolon = 'Ожидается точка с запятой (";").';
msgExpectedKeywordNamespace = 'Ожидается ключевое слово "namespace".';
msgExpectedOpenedParenthesis = 'Ожидается открывающая круглая скобка ("(").';
msgExpectedClosedParenthesis = 'Ожидается закрывающая круглая скобка (")").';
msgExpectedOpenedCurlyBracket = 'Ожидается открывающая фигурная скобка ("{").';
msgExpectedClosedCurlyBracket = 'Ожидается закрывающая фигурная скобка ("}").';
msgExpectedOpenedSquareBracket = 'Ожидается открывающая квадратная скобка ("[").';
msgExpectedClosedSquareBracket = 'Ожидается закрывающая квадратная скобка ("]").';
msgExpectedIdentifierOfNamespace = 'Ожидается идентификатор пространства имён.';
msgExpectedIdentifierOfDataType = 'Ожидается идентификатор типа данных.';
msgExpectedIdentifierOfConstant = 'Ожидается идентификатор константы.';
msgExpectedIdentifierOfException = 'Ожидается идентификатор исключения.';
msgExpectedIdentifierOfStructure = 'Ожидается идентификатор структуры.';
msgExpectedIdentifierOfVariable = 'Ожидается идентификатор переменной.';
msgExpectedIdentifierOfArgument = 'Ожидается идентификатор аргумента.';
msgExpectedIdentifierOfFunction = 'Ожидается идентификатор функции.';
msgExpectedIdentifierOfField = 'Ожидается идентификатор поля.';
msgExceptionNotSupported = 'Исключения не поддерживаются при текущей разрядности кода.';
msgOperationNotSupportedOS = 'Операция не поддерживается при текущей разрядности кода.';
msgOperationNotSupportedEX = 'Операция не поддерживается при текущих расширениях x86.';
msgTypeMustBeBoolean = 'Тип выражения должен быть boolean.';
msgTypeMustBeShort = 'Тип выражения должен быть short.';
msgTypeMustBeInt = 'Тип выражения должен быть int.';
msgTypeMustBeFloat = 'Тип выражения должен быть float.';
msgTypeMustBeNumeric = 'Тип выражения должен быть числовым.';
msgTypeMustBeCompound = 'Тип выражения должен быть составным.';
msgTypeNotApplicableToConst = 'Этот тип данных не подходит для констант.';
msgTypeNotApplicableToFunc = 'Этот тип данных не подходит для возвращаемого значения функции.';
msgTypeNotApplicableToVar = 'Этот тип данных не подходит для переменных.';
msgTypeNotSupported = 'Этот тип данных не поддерживается при текущей разрядности.';
msgTypeReserved = 'Этот тип данных зарезервирован и не должен использоваться.';
msgEntryPointNotFound = 'Точка входа в программу не найдена.';
msgEntryPointAlreadyExists = 'Одна точка входа в программу уже существует.';
msgInterruptMustReturnVoid = 'Функция-прерывание всегда должна возвращать void.';
msgNamespaceSystemNotFound = 'Системное пространство имён не найдено: namespace System.';
msgNamespaceAlreadyExists = 'Пространство имён с таким именем уже существует.';
msgNamespaceAlreadyImported = 'Пространство имён уже импортировано.';
msgAlreadyExistsIdentifier = 'Объект с таким идентификатором уже существует.';
msgAlreadyExistsFinalization = 'Процедура финализации уже существует.';
msgAlreadyExistsInitialization = 'Процедура инициализации уже существует.';
msgCannotAssignDataType = 'Нельзя присвоить приёмнику выражение этого типа данных.';
msgCannotApplyOperation = 'Нельзя применить к данным этого типа эту операцию.';
msgCannotCastToType = 'Нельзя привести выражение к этому типу данных.';
msgCompoundIndexOutOfBounds = 'Cоставной тип данных: индекс выходит из диапазона.';
msgSpecialFunctionError = 'Ошибка в заявлении специальной функции new|dispose.';
msgSpecialFunctionMustInSystem = 'Специальная функция может быть только внутри System.';
msgSpecialFunctionMustNoInterrupt = 'Специальная функция не может быть прерыванием.';
msgIntegerDivisionByZero = 'Ошибка деления целого числа на ноль.';
implementation
{ TranslatorNamespacesBuilder }
class function TranslatorNamespacesBuilder.pack4IntUS(const value: ultra): long; assembler;
var
oldESI: int;
oldEDI: int;
asm
{ ВХОД: edx – value
ecx – результат }
mov [oldESI], esi
mov [oldEDI], edi
mov esi, edx
mov edi, ecx
mov ecx, $04
@0: mov eax, [esi + ecx*4 - $04]
cmp eax, $0000
jge @1
xor eax, eax
jmp @2
@1: cmp eax, $ffff
jle @2
mov eax, $ffff
@2: mov [edi + ecx*2 - $02], ax
loop @0
mov esi, [oldESI]
mov edi, [oldEDI]
end;
constructor TranslatorNamespacesBuilder.create(operandSize, extension: int);
var
typCount: int;
types: TypeDescriptor_Array1d;
begin
inherited create();
types := TypeDescriptor_Array1d(Interface_Array1d_create([
TranslatorTypePrimitive.create(TranslatorType.KIND_VOID) as TypeDescriptor,
TranslatorTypePrimitive.create(TranslatorType.KIND_BOOLEAN) as TypeDescriptor,
TranslatorTypePrimitive.create(TranslatorType.KIND_CHAR) as TypeDescriptor,
TranslatorTypePrimitive.create(TranslatorType.KIND_BYTE) as TypeDescriptor,
TranslatorTypePrimitive.create(TranslatorType.KIND_SHORT) as TypeDescriptor,
TranslatorTypePrimitive.create(TranslatorType.KIND_INT) as TypeDescriptor,
TranslatorTypePrimitive.create(TranslatorType.KIND_LONG) as TypeDescriptor,
TranslatorTypePrimitive.create(TranslatorType.KIND_ULTRA) as TypeDescriptor,
TranslatorTypePrimitive.create(TranslatorType.KIND_FLOAT) as TypeDescriptor,
TranslatorTypePrimitive.create(TranslatorType.KIND_DOUBLE) as TypeDescriptor,
TranslatorTypePrimitive.create(TranslatorType.KIND_REAL) as TypeDescriptor,
TranslatorTypePrimitive.create(TranslatorType.KIND_XVECTOR) as TypeDescriptor
]));
typCount := length(types);
self.fldOperandSize := operandSize;
self.fldExtension := extension;
self.fldStayPosition := -1;
self.initTypesCount := typCount;
self.lexersCount := 0;
self.namespacesCount := 0;
self.typesCount := typCount;
self.lexers := nil;
self.namespaces := nil;
self.types := types;
self.systemNamespace := nil;
self.entryPoint := nil;
self.fldTypVoid := types[0] as TypePrimitive;
self.fldTypBoolean := types[1] as TypePrimitive;
self.fldTypChar := types[2] as TypePrimitive;
self.fldTypByte := types[3] as TypePrimitive;
self.fldTypShort := types[4] as TypePrimitive;
self.fldTypInt := types[5] as TypePrimitive;
self.fldTypLong := types[6] as TypePrimitive;
self.fldTypUltra := types[7] as TypePrimitive;
self.fldTypFloat := types[8] as TypePrimitive;
self.fldTypDouble := types[9] as TypePrimitive;
self.fldTypReal := types[10] as TypePrimitive;
self.fldTypXVector := types[11] as TypePrimitive;
end;
procedure TranslatorNamespacesBuilder.clear();
var
i: int;
tc: int;
nc: int;
itc: int;
types: TypeDescriptor_Array1d;
namespaces: Namespace_Array1d;
begin
tc := self.typesCount;
nc := self.namespacesCount;
itc := self.initTypesCount;
types := self.types;
namespaces := self.namespaces;
self.fldStayPosition := -1;
self.lexersCount := 0;
self.namespacesCount := 0;
self.typesCount := itc;
self.lexers := nil;
self.namespaces := nil;
self.systemNamespace := nil;
self.entryPoint := nil;
for i := nc - 1 downto 0 do begin
namespaces[i].clear();
end;
for i := tc - 1 downto itc do begin
types[i] := nil;
end;
end;
procedure TranslatorNamespacesBuilder.addLexer(lexemes: Lexer);
var
c: int;
lexers: Lexer_Array1d;
newlexers: Lexer_Array1d;
begin
c := self.lexersCount;
lexers := self.lexers;
if length(lexers) = c then begin
newlexers := Lexer_Array1d(Interface_Array1d_create((c shl 1) + 1));
arraycopyInterfaces(lexers, 0, newlexers, 0, c);
self.lexers := newlexers;
lexers := newlexers;
end;
lexers[c] := lexemes;
self.lexersCount := c + 1;
end;
procedure TranslatorNamespacesBuilder.buildNamespaces();
var
i: int;
j: int;
t: int;
lc: int;
nc: int;
position: int;
lexemes: Lexer;
buffered: Namespace;
imported: Namespace;
currentNamespace: Namespace;
currentEntry: NamespaceEntry;
lexers: Lexer_Array1d;
namespaces: Namespace_Array1d;
identifier: UnicodeString;
begin
lc := self.lexersCount - 1;
lexers := self.lexers;
if lc < 0 then begin
exit;
end;
{ Поиск пространств имён в исходном тексте }
for i := 0 to lc do begin
lexemes := lexers[i];
position := 0;
while lexemes.getType(position) = TranslatorLexer.KW_IMPORT do begin
inc(position);
if lexemes.getType(position) <> TranslatorLexer.IDENTIFIER then begin
raise CompileError.create(msgExpectedIdentifierOfNamespace, lexemes, position);
end;
inc(position);
if lexemes.getType(position) <> TranslatorLexer.SEMICOLON then begin
raise CompileError.create(msgExpectedSemicolon, lexemes, position);
end;
inc(position);
end;
case lexemes.getType(position) of
TranslatorLexer.KW_NAMESPACE: begin
inc(position);
if lexemes.getType(position) <> TranslatorLexer.IDENTIFIER then begin
raise CompileError.create(msgExpectedIdentifierOfNamespace, lexemes, position);
end;
identifier := lexemes.getValueUString(position);
inc(position);
if lexemes.getType(position) <> TranslatorLexer.OPENED_CURLY_BRACKET then begin
raise CompileError.create(msgExpectedOpenedCurlyBracket, lexemes, position);
end;
inc(position);
currentNamespace := TranslatorNamespace.create(identifier, lexemes, operandSize);
currentNamespace.declarePosition := position - 2;
currentNamespace.startPosition := position;
addNamespace(currentNamespace);
if identifier = NAMESPACE_SYSTEM then begin
systemNamespace := currentNamespace;
namespaces := self.namespaces;
arraycopyInterfaces(namespaces, 0, namespaces, 1, self.namespacesCount - 1);
namespaces[0] := currentNamespace;
end;
position := skipCurlyBrackets(lexemes, position - 1);
end;
TranslatorLexer.OPENED_CURLY_BRACKET: begin
if entryPoint <> nil then begin
raise CompileError.create(msgEntryPointAlreadyExists, lexemes, position);
end;
currentNamespace := TranslatorNamespace.create('', lexemes, operandSize);
currentNamespace.startPosition := position;
entryPoint := currentNamespace.addFunction(true, FUNCTION_MAIN,
TranslatorGlobalFunction.CODE_TYPE_NORMAL, typeVoid);
entryPoint.declarePosition := -1;
entryPoint.startPosition := position;
addNamespace(currentNamespace);
position := skipCurlyBrackets(lexemes, position);
end;
TranslatorLexer.IDENTIFIER: begin
if entryPoint <> nil then begin
raise CompileError.create(msgEntryPointAlreadyExists, lexemes, position);
end;
inc(position);
if lexemes.getType(position) <> TranslatorLexer.OPENED_PARENTHESIS then begin
raise CompileError.create(msgExpectedOpenedParenthesis, lexemes, position);
end;
dec(position);
currentNamespace := TranslatorNamespace.create('', lexemes, position);
currentNamespace.startPosition := position;
entryPoint := currentNamespace.addFunction(true, lexemes.getValueUString(position),
TranslatorGlobalFunction.CODE_TYPE_NORMAL, typeVoid);
entryPoint.declarePosition := position;
addNamespace(currentNamespace);
position := skipParenthesis(lexemes, position + 1);
if lexemes.getType(position) <> TranslatorLexer.OPENED_CURLY_BRACKET then begin
raise CompileError.create(msgExpectedOpenedCurlyBracket, lexemes, position);
end;
entryPoint.startPosition := position;
position := skipCurlyBrackets(lexemes, position);
end;
else
raise CompileError.create(msgExpectedKeywordNamespace, lexemes, position);
end;
while lexemes.getType(position) = TranslatorLexer.KW_NAMESPACE do begin
inc(position);
if lexemes.getType(position) <> TranslatorLexer.IDENTIFIER then begin
raise CompileError.create(msgExpectedIdentifierOfNamespace, lexemes, position);
end;
identifier := lexemes.getValueUString(position);
inc(position);
if lexemes.getType(position) <> TranslatorLexer.OPENED_CURLY_BRACKET then begin
raise CompileError.create(msgExpectedOpenedCurlyBracket, lexemes, position);
end;
inc(position);
currentNamespace := TranslatorNamespace.create(identifier, lexemes, operandSize);
currentNamespace.declarePosition := position - 2;
currentNamespace.startPosition := position;
addNamespace(currentNamespace);
if identifier = NAMESPACE_SYSTEM then begin
systemNamespace := currentNamespace;
namespaces := self.namespaces;
arraycopyInterfaces(namespaces, 0, namespaces, 1, self.namespacesCount - 1);
namespaces[0] := currentNamespace;
end;
position := skipCurlyBrackets(lexemes, position - 1);
end;
end;
{ Проверка наличия необходимых элементов: системного пространства имён и точки входа }
if systemNamespace = nil then begin
raise CompileError.create(msgNamespaceSystemNotFound, lexers[0], 0);
end;
if entryPoint = nil then begin
raise CompileError.create(msgEntryPointNotFound, lexers[0], 0);
end;
{ Поиск пространств имён с одинаковыми именами }
nc := self.namespacesCount - 1;
namespaces := self.namespaces;
for i := 1 to nc do begin
identifier := namespaces[i - 1].name;
for j := i to nc do begin
currentNamespace := namespaces[j];
if currentNamespace.name = identifier then begin
raise CompileError.create(msgNamespaceAlreadyExists, currentNamespace.lexemes,
currentNamespace.declarePosition);
end;
end;
end;
{ Подключение импортов }
buffered := systemNamespace;
for i := 0 to nc do begin
currentNamespace := namespaces[i];
currentNamespace.addImport(buffered);
lexemes := currentNamespace.lexemes;
position := 0;
while lexemes.getType(position) = TranslatorLexer.KW_IMPORT do begin
inc(position);
identifier := lexemes.getValueUString(position);
imported := findNamespace(identifier);
if imported = nil then begin
raise CompileError.create(msgExpectedIdentifierOfNamespace, lexemes, position);
end;
if currentNamespace.isImported(identifier) then begin
raise CompileError.create(msgNamespaceAlreadyImported, lexemes, position);
end;
currentNamespace.addImport(imported);
inc(position, 2);
end;
end;
{ Поиск членов пространств имён в исходном тексте }
for i := 0 to nc do begin
currentNamespace := namespaces[i];
if length(currentNamespace.name) <= 0 then begin
continue;
end;
lexemes := currentNamespace.lexemes;
position := currentNamespace.startPosition;
t := lexemes.getType(position);
while (t <> TranslatorLexer.CLOSED_CURLY_BRACKET) and (t <> TranslatorLexer.NULL) do begin
position := parseEntry(currentNamespace, lexemes, position);
t := lexemes.getType(position);
end;
if t <> TranslatorLexer.CLOSED_CURLY_BRACKET then begin
raise CompileError.create(msgExpectedClosedCurlyBracket, lexemes, position);
end;
end;
{ Добавление аргументов к функции – точке входа }
position := entryPoint.declarePosition + 2;
if position > 1 then begin
currentNamespace := entryPoint.owner;
lexemes := currentNamespace.lexemes;
position := parseArguments(currentNamespace, lexemes, position, entryPoint.functionType);
if lexemes.getType(position) <> TranslatorLexer.CLOSED_PARENTHESIS then begin
raise CompileError.create(msgExpectedClosedParenthesis, lexemes, position);
end;
end;
{ Поиск полей структур в исходном тексте }
for i := 0 to nc do begin
currentNamespace := namespaces[i];
lexemes := currentNamespace.lexemes;
lc := currentNamespace.getEntriesCount() - 1;
for j := 0 to lc do begin
currentEntry := currentNamespace.getEntry(j);
if currentEntry is TypeStructure then begin
parseFields(currentEntry as TypeStructure, lexemes);
end;
end;
end;
end;
function TranslatorNamespacesBuilder.getNamespacesCount(): int;
begin
result := namespacesCount;
end;
function TranslatorNamespacesBuilder.getNamespace(index: int): Namespace;
begin
if (index < 0) or (index >= namespacesCount) then begin
raise IndexOutOfBoundsException.create(msgIndexOutOfBounds);
end;
result := namespaces[index];
end;
function TranslatorNamespacesBuilder.getSystemNamespace(): Namespace;
begin
result := systemNamespace;
end;
function TranslatorNamespacesBuilder.getEntryPoint(): GlobalFunction;
begin
result := entryPoint;
end;
function TranslatorNamespacesBuilder.findNamespace(const name: UnicodeString): Namespace;
var
i: int;
current: Namespace;
namespaces: Namespace_Array1d;
begin
namespaces := self.namespaces;
for i := self.namespacesCount - 1 downto 0 do begin
current := namespaces[i];
if current.name = name then begin
result := current;
exit;
end;
end;
result := nil;
end;
procedure TranslatorNamespacesBuilder.addNamespace(space: Namespace);
var
c: int;
namespaces: Namespace_Array1d;
newnamespaces: Namespace_Array1d;
begin
c := self.namespacesCount;
namespaces := self.namespaces;
if length(namespaces) = c then begin
newnamespaces := Namespace_Array1d(Interface_Array1d_create((c shl 1) + 1));
arraycopyInterfaces(namespaces, 0, newnamespaces, 0, c);
self.namespaces := newnamespaces;
namespaces := newnamespaces;
end;
namespaces[c] := space;
self.namespacesCount := c + 1;
end;
procedure TranslatorNamespacesBuilder.parseFields(structure: TypeStructure; lexemes: Lexer);
var
position: int;
fldPublic: boolean;
fldType: TypeDescriptor;
fldName: UnicodeString;
fldResult: StructureField;
structureAsEntry: NamespaceEntry;
where: Namespace;
begin
structure.updateSize();
structureAsEntry := structure as NamespaceEntry;
position := structureAsEntry.startPosition;
if position < 0 then begin
exit;
end;
where := structureAsEntry.owner;
repeat
case lexemes.getType(position) of
TranslatorLexer.CLOSED_CURLY_BRACKET: begin
break;
end;
TranslatorLexer.NULL: begin
raise CompileError.create(msgExpectedClosedCurlyBracket, lexemes, position);
end;
TranslatorLexer.KW_PUBLIC: begin
fldPublic := true;
inc(position);
end;
else
fldPublic := false;
end;
fldType := parseType(where, position);
position := stayPosition;
if not fldType.isMatchForVariable() then begin
raise CompileError.create(msgTypeNotApplicableToVar, lexemes, position);
end;
fldName := '';
if lexemes.getType(position) = TranslatorLexer.IDENTIFIER then begin
fldName := lexemes.getValueUString(position);
if structure.findField(fldName, true) <> nil then begin
raise CompileError.create(msgAlreadyExistsIdentifier, lexemes, position);
end;
fldResult := structure.addField(fldPublic, fldType, fldName);
fldResult.declarePosition := position;
inc(position);
end else begin
structure.addField(fldPublic, fldType, fldName);
end;
if lexemes.getType(position) <> TranslatorLexer.SEMICOLON then begin
raise CompileError.create(msgExpectedSemicolon, lexemes, position);
end;
inc(position);
until false;
end;
function TranslatorNamespacesBuilder.parseEntry(where: Namespace; lexemes: Lexer;
position: int): int;
var
epublic: boolean;
begin
epublic := false;
if lexemes.getType(position) = TranslatorLexer.KW_PUBLIC then begin
epublic := true;
inc(position);
end;
case lexemes.getType(position) of
TranslatorLexer.KW_CONST:
result := parseConstant(where, lexemes, position + 1, epublic);
TranslatorLexer.KW_EXCEPTION:
result := parseException(where, lexemes, position + 1, epublic);
TranslatorLexer.KW_STRUCT:
result := parseStructure(where, lexemes, position + 1, epublic);
else
result := parseVarOrFunc(where, lexemes, position, epublic);
end;
end;
function TranslatorNamespacesBuilder.parseConstant(where: Namespace; lexemes: Lexer;
position: int; epublic: boolean): int;
var
declarePosition: int;
constTypeKind: int;
constType: TypeDescriptor;
constValue: GlobalConstant;
constResult: GlobalConstant;
constIdent: UnicodeString;
begin
constType := parseType(where, position);
constTypeKind := constType.kind;
position := stayPosition;
if not constType.isMatchForConstant() then begin
raise CompileError.create(msgTypeNotApplicableToConst, lexemes, position);
end;
if lexemes.getType(position) <> TranslatorLexer.IDENTIFIER then begin
raise CompileError.create(msgExpectedIdentifierOfConstant, lexemes, position);
end;
constIdent := lexemes.getValueUString(position);
if where.findEntry(constIdent, false) <> nil then begin
raise CompileError.create(msgAlreadyExistsIdentifier, lexemes, position);
end;
declarePosition := position;
inc(position);
if lexemes.getType(position) <> TranslatorLexer.ASSIGN then begin
raise CompileError.create(msgExpectedAssign, lexemes, position);
end;
constValue := parseConst(where, position + 1);
position := stayPosition;
if not possibleAssign(constTypeKind, constValue) then begin
raise CompileError.create(msgCannotAssignDataType, lexemes, declarePosition + 1);
end;
case constTypeKind of
TranslatorType.KIND_BOOLEAN, TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE,
TranslatorType.KIND_SHORT, TranslatorType.KIND_INT, TranslatorType.KIND_LONG,
TranslatorType.KIND_FLOAT, TranslatorType.KIND_DOUBLE, TranslatorType.KIND_REAL:
constResult := where.addConstant(epublic, constIdent, constType,
constValue.realValue);
TranslatorType.KIND_ULTRA:
constResult := where.addConstantUltra(epublic, constIdent, constType,
constValue.getUltraValue());
TranslatorType.KIND_XVECTOR:
constResult := where.addConstantXVector(epublic, constIdent, constType,
constValue.getXVectorValue());
else
constResult := nil;
end;
constResult.declarePosition := declarePosition;
if lexemes.getType(position) <> TranslatorLexer.SEMICOLON then begin
raise CompileError.create(msgExpectedSemicolon, lexemes, position);
end;
result := position + 1;
end;
function TranslatorNamespacesBuilder.parseException(where: Namespace; lexemes: Lexer;
position: int; epublic: boolean): int;
label
label0;
var
declarePosition: int;
exceptAncestor: GlobalException;
exceptResult: GlobalException;
exceptIdent: UnicodeString;
place: Namespace;
entry: NamespaceEntry;
ident: UnicodeString;
begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
raise CompileError.create(msgExceptionNotSupported, lexemes, position);
end;
if lexemes.getType(position) <> TranslatorLexer.IDENTIFIER then begin
raise CompileError.create(msgExpectedIdentifierOfException, lexemes, position);
end;
exceptIdent := lexemes.getValueUString(position);
if where.findEntry(exceptIdent, false) <> nil then begin
raise CompileError.create(msgAlreadyExistsIdentifier, lexemes, position);
end;
declarePosition := position;
inc(position);
if lexemes.getType(position) = TranslatorLexer.OPENED_PARENTHESIS then begin
inc(position);
if lexemes.getType(position) <> TranslatorLexer.IDENTIFIER then begin
raise CompileError.create(msgExpectedIdentifierOfException, lexemes, position);
end;
ident := lexemes.getValueUString(position);
entry := where.findEntry(ident, true);
if entry = nil then begin
place := findNamespace(ident);
if place = nil then begin
raise CompileError.create(msgExpectedException, lexemes, position);
end;
inc(position);
if lexemes.getType(position) <> TranslatorLexer.PERIOD then begin
raise CompileError.create(msgExpectedPeriod, lexemes, position);
end;
inc(position);
if lexemes.getType(position) <> TranslatorLexer.IDENTIFIER then begin
raise CompileError.create(msgExpectedIdentifierOfException, lexemes, position);
end;
ident := lexemes.getValueUString(position);
entry := place.findEntry(ident, false);
if not (entry is GlobalException) or not where.isVisible(entry) then begin
raise CompileError.create(msgExpectedIdentifierOfException, lexemes, position);
end;
exceptAncestor := entry as GlobalException;
end else
if entry is GlobalException then begin
exceptAncestor := entry as GlobalException;
end else begin
raise CompileError.create(msgExpectedIdentifierOfException, lexemes, position);
end;
inc(position);
if lexemes.getType(position) <> TranslatorLexer.CLOSED_PARENTHESIS then begin
raise CompileError.create(msgExpectedClosedParenthesis, lexemes, position);
end;
inc(position);
end else begin
exceptAncestor := nil;
place := systemNamespace;
if place <> nil then begin
entry := place.findEntry(EXCEPTION_EXCEPTION, false);
if entry is GlobalException then begin
exceptAncestor := entry as GlobalException;
goto label0;
end;
entry := place.findEntry(EXCEPTION_THROWABLE, false);
if entry is GlobalException then begin
exceptAncestor := entry as GlobalException;
end;
label0:
end;
end;
exceptResult := where.addException(epublic, exceptIdent, exceptAncestor);
exceptResult.declarePosition := declarePosition;
if lexemes.getType(position) <> TranslatorLexer.SEMICOLON then begin
raise CompileError.create(msgExpectedSemicolon, lexemes, position);
end;
result := position + 1;
end;
function TranslatorNamespacesBuilder.parseStructure(where: Namespace; lexemes: Lexer;
position: int; epublic: boolean): int;
var
declarePosition: int;
structAncestor: TypeStructure;
structResult: NamespaceEntry;
structIdent: UnicodeString;
place: Namespace;
entry: NamespaceEntry;
ident: UnicodeString;
begin
if lexemes.getType(position) <> TranslatorLexer.IDENTIFIER then begin
raise CompileError.create(msgExpectedIdentifierOfStructure, lexemes, position);
end;
structIdent := lexemes.getValueUString(position);
if where.findEntry(structIdent, false) <> nil then begin
raise CompileError.create(msgAlreadyExistsIdentifier, lexemes, position);
end;
declarePosition := position;
inc(position);
if lexemes.getType(position) = TranslatorLexer.OPENED_PARENTHESIS then begin
inc(position);
if lexemes.getType(position) <> TranslatorLexer.IDENTIFIER then begin
raise CompileError.create(msgExpectedIdentifierOfStructure, lexemes, position);
end;
ident := lexemes.getValueUString(position);
entry := where.findEntry(ident, true);
if entry = nil then begin
place := findNamespace(ident);
if place = nil then begin
raise CompileError.create(msgExpectedStructure, lexemes, position);
end;
inc(position);
if lexemes.getType(position) <> TranslatorLexer.PERIOD then begin
raise CompileError.create(msgExpectedPeriod, lexemes, position);
end;
inc(position);
if lexemes.getType(position) <> TranslatorLexer.IDENTIFIER then begin
raise CompileError.create(msgExpectedIdentifierOfStructure, lexemes, position);
end;
ident := lexemes.getValueUString(position);
entry := place.findEntry(ident, false);
if not (entry is TypeStructure) or not where.isVisible(entry) then begin
raise CompileError.create(msgExpectedIdentifierOfStructure, lexemes, position);
end;
structAncestor := entry as TypeStructure;
end else
if entry is TypeStructure then begin
structAncestor := entry as TypeStructure;
end else begin
raise CompileError.create(msgExpectedIdentifierOfStructure, lexemes, position);
end;
inc(position);
if lexemes.getType(position) <> TranslatorLexer.CLOSED_PARENTHESIS then begin
raise CompileError.create(msgExpectedClosedParenthesis, lexemes, position);
end;
inc(position);
end else begin
structAncestor := nil;
place := systemNamespace;
if place <> nil then begin
entry := place.findEntry(STRUCTURE_POINTER, false);
if entry is TypeStructure then begin
structAncestor := entry as TypeStructure;
end;
end;
end;
structResult := where.addStructureExt(epublic, structIdent, structAncestor);
structResult.declarePosition := declarePosition;
case lexemes.getType(position) of
TranslatorLexer.OPENED_CURLY_BRACKET: begin
structResult.startPosition := position + 1;
position := skipCurlyBrackets(lexemes, position);
end;
TranslatorLexer.SEMICOLON: begin
structResult.startPosition := -1;
inc(position);
end;
else
raise CompileError.create(msgExpectedOpenedCurlyBracket, lexemes, position);
end;
result := position;
end;
function TranslatorNamespacesBuilder.parseVarOrFunc(where: Namespace; lexemes: Lexer;
position: int; epublic: boolean): int;
var
i: int;
declarePosition: int;
retKind: int;
argKind: int;
codeType: int;
tempType: TypeDescriptor;
entryType: TypeDescriptor;
varResult: GlobalVariable;
funcResult: GlobalFunction;
entryName: UnicodeString;
resFunc: TypeFunction;
newFunc: TypeFunction;
begin
codeType := 0;
case lexemes.getType(position) of
TranslatorLexer.KW_INITIALIZATION: begin
declarePosition := position;
if where.findEntry(FUNCTION_INITIALIZATION, false) <> nil then begin
raise CompileError.create(msgAlreadyExistsInitialization, lexemes, position);
end;
inc(position);
if lexemes.getType(position) <> TranslatorLexer.OPENED_CURLY_BRACKET then begin
raise CompileError.create(msgExpectedOpenedCurlyBracket, lexemes, position);
end;
funcResult := where.addFunction(epublic, FUNCTION_INITIALIZATION, 0, typeVoid);
funcResult.startPosition := position;
funcResult.declarePosition := declarePosition;
result := skipCurlyBrackets(lexemes, position);
exit;
end;
TranslatorLexer.KW_FINALIZATION: begin
declarePosition := position;
if where.findEntry(FUNCTION_FINALIZATION, false) <> nil then begin
raise CompileError.create(msgAlreadyExistsFinalization, lexemes, position);
end;
inc(position);
if lexemes.getType(position) <> TranslatorLexer.OPENED_CURLY_BRACKET then begin
raise CompileError.create(msgExpectedOpenedCurlyBracket, lexemes, position);
end;
funcResult := where.addFunction(epublic, FUNCTION_FINALIZATION, 0, typeVoid);
funcResult.startPosition := position;
funcResult.declarePosition := declarePosition;
result := skipCurlyBrackets(lexemes, position);
exit;
end;
TranslatorLexer.KW_INTERRUPT: begin
codeType := codeType or TranslatorGlobalFunction.CODE_TYPE_INTERRUPT;
inc(position);
end;
end;
case lexemes.getType(position) of
TranslatorLexer.KW_ASSEMBLER: begin
codeType := codeType or TranslatorGlobalFunction.CODE_TYPE_ASSEMBLER;
inc(position);
end;
TranslatorLexer.KW_PUREASSEMBLER: begin
codeType := codeType or TranslatorGlobalFunction.CODE_TYPE_PUREASSEMBLER;
inc(position);
end;
end;
case operandSize of
TranslatorType.SIZE_16_BIT: begin
retKind := TranslatorType.KIND_CHAR;
argKind := TranslatorType.KIND_SHORT;
end;
TranslatorType.SIZE_32_BIT: begin
retKind := TranslatorType.KIND_INT;
argKind := TranslatorType.KIND_INT;
end;
TranslatorType.SIZE_64_BIT: begin
retKind := TranslatorType.KIND_LONG;
argKind := TranslatorType.KIND_INT;
end;
else
retKind := 0;
argKind := 0;
end;
entryType := parseType(where, position);
position := stayPosition;
declarePosition := position;
case lexemes.getType(position) of
TranslatorLexer.IDENTIFIER: begin
if ((codeType and TranslatorGlobalFunction.CODE_TYPE_INTERRUPT) <> 0) and
(entryType.kind <> TranslatorType.KIND_VOID) then begin
raise CompileError.create(msgInterruptMustReturnVoid, lexemes, position);
end;
entryName := lexemes.getValueUString(position);
if where.findEntry(entryName, false) <> nil then begin
raise CompileError.create(msgAlreadyExistsIdentifier, lexemes, position);
end;
inc(position);
case lexemes.getType(position) of
TranslatorLexer.SEMICOLON: begin
if not entryType.isMatchForVariable() or (codeType <> 0) then begin
raise CompileError.create(msgExpectedOpenedParenthesis, lexemes, position);
end;
inc(position);
varResult := where.addVariable(epublic, entryName, entryType);
varResult.declarePosition := declarePosition;
end;
TranslatorLexer.OPENED_PARENTHESIS: begin
if not entryType.isMatchForReturnType() then begin
raise CompileError.create(msgTypeNotApplicableToFunc, lexemes, position - 1);
end;
funcResult := where.addFunction(epublic, entryName, codeType, entryType);
position := parseArguments(where, lexemes, position + 1, funcResult.functionType);
if lexemes.getType(position) <> TranslatorLexer.CLOSED_PARENTHESIS then begin
raise CompileError.create(msgExpectedClosedParenthesis, lexemes, position);
end;
inc(position);
if lexemes.getType(position) <> TranslatorLexer.OPENED_CURLY_BRACKET then begin
raise CompileError.create(msgExpectedOpenedCurlyBracket, lexemes, position);
end;
funcResult.startPosition := position;
funcResult.declarePosition := declarePosition;
position := skipCurlyBrackets(lexemes, position);
end;
else
if entryType.isMatchForVariable() and (codeType = 0) then begin
raise CompileError.create(msgExpectedSemicolon, lexemes, position);
end else begin
raise CompileError.create(msgExpectedOpenedParenthesis, lexemes, position);
end;
end;
end;
TranslatorLexer.KW_DISPOSE: begin
if where <> systemNamespace then begin
raise CompileError.create(msgSpecialFunctionMustInSystem, lexemes, position);
end;
if (codeType and TranslatorGlobalFunction.CODE_TYPE_INTERRUPT) <> 0 then begin
raise CompileError.create(msgSpecialFunctionMustNoInterrupt, lexemes, position);
end;
inc(position);
if lexemes.getType(position) <> TranslatorLexer.OPENED_PARENTHESIS then begin
raise CompileError.create(msgExpectedOpenedParenthesis, lexemes, position);
end;
newFunc := TranslatorTypeFunction.create(operandSize, entryType);
position := parseArguments(where, lexemes, position + 1, newFunc);
if lexemes.getType(position) <> TranslatorLexer.CLOSED_PARENTHESIS then begin
raise CompileError.create(msgExpectedClosedParenthesis, lexemes, position);
end;
inc(position);
if lexemes.getType(position) <> TranslatorLexer.OPENED_CURLY_BRACKET then begin
raise CompileError.create(msgExpectedOpenedCurlyBracket, lexemes, position);
end;
if newFunc.getArgumentsCount() <> 1 then begin
raise CompileError.create(msgSpecialFunctionError, lexemes, declarePosition);
end;
if where.findEntry(FUNCTION_DISPOSE, false) <> nil then begin
raise CompileError.create(msgAlreadyExistsIdentifier, lexemes, declarePosition);
end;
if entryType.kind <> TranslatorType.KIND_VOID then begin
raise CompileError.create(msgSpecialFunctionError, lexemes, declarePosition);
end;
funcResult := where.addFunction(epublic, FUNCTION_DISPOSE, codeType, entryType);
resFunc := funcResult.functionType;
with newFunc.getArgument(0) do begin
tempType := dataType;
if tempType.kind <> retKind then begin
raise CompileError.create(msgSpecialFunctionError, lexemes, declarePosition);
end;
resFunc.addArgument(tempType, name);
end;
funcResult.startPosition := position;
funcResult.declarePosition := declarePosition;
position := skipCurlyBrackets(lexemes, position);
end;
TranslatorLexer.KW_NEW: begin
if where <> systemNamespace then begin
raise CompileError.create(msgSpecialFunctionMustInSystem, lexemes, position);
end;
if (codeType and TranslatorGlobalFunction.CODE_TYPE_INTERRUPT) <> 0 then begin
raise CompileError.create(msgSpecialFunctionMustNoInterrupt, lexemes, position);
end;
inc(position);
if lexemes.getType(position) <> TranslatorLexer.OPENED_PARENTHESIS then begin
raise CompileError.create(msgExpectedOpenedParenthesis, lexemes, position);
end;
newFunc := TranslatorTypeFunction.create(operandSize, entryType);
position := parseArguments(where, lexemes, position + 1, newFunc);
if lexemes.getType(position) <> TranslatorLexer.CLOSED_PARENTHESIS then begin
raise CompileError.create(msgExpectedClosedParenthesis, lexemes, position);
end;
inc(position);
if lexemes.getType(position) <> TranslatorLexer.OPENED_CURLY_BRACKET then begin
raise CompileError.create(msgExpectedOpenedCurlyBracket, lexemes, position);
end;
case newFunc.getArgumentsCount() of
1: begin
if where.findEntry(FUNCTION_NEW_STRUCT, false) <> nil then begin
raise CompileError.create(msgAlreadyExistsIdentifier, lexemes, declarePosition);
end;
if entryType.kind <> retKind then begin
raise CompileError.create(msgSpecialFunctionError, lexemes, declarePosition);
end;
funcResult := where.addFunction(epublic, FUNCTION_NEW_STRUCT, codeType, entryType);
resFunc := funcResult.functionType;
with newFunc.getArgument(0) do begin
tempType := dataType;
if tempType.kind <> argKind then begin
raise CompileError.create(msgSpecialFunctionError, lexemes, declarePosition);
end;
resFunc.addArgument(tempType, name);
end;
end;
2: begin
if where.findEntry(FUNCTION_NEW_ARRAY, false) <> nil then begin
raise CompileError.create(msgAlreadyExistsIdentifier, lexemes, declarePosition);
end;
if entryType.kind <> retKind then begin
raise CompileError.create(msgSpecialFunctionError, lexemes, declarePosition);
end;
funcResult := where.addFunction(epublic, FUNCTION_NEW_ARRAY, codeType, entryType);
resFunc := funcResult.functionType;
for i := 0 to 1 do with newFunc.getArgument(i) do begin
tempType := dataType;
if tempType.kind <> argKind then begin
raise CompileError.create(msgSpecialFunctionError, lexemes, declarePosition);
end;
resFunc.addArgument(tempType, name);
end;
end;
else
raise CompileError.create(msgSpecialFunctionError, lexemes, declarePosition);
end;
funcResult.startPosition := position;
funcResult.declarePosition := declarePosition;
position := skipCurlyBrackets(lexemes, position);
end;
else
if entryType.isMatchForVariable() and (codeType = 0) then begin
raise CompileError.create(msgExpectedIdentifierOfVariable, lexemes, position);
end else begin
raise CompileError.create(msgExpectedIdentifierOfFunction, lexemes, position);
end;
end;
result := position;
end;
function TranslatorNamespacesBuilder.parseArguments(where: Namespace; lexemes: Lexer;
position: int; destination: TypeFunction): int;
var
argument: FunctionArgument;
argType: TypeDescriptor;
argName: UnicodeString;
begin
if lexemes.getType(position) <> TranslatorLexer.CLOSED_PARENTHESIS then begin
repeat
argType := parseType(where, position);
position := stayPosition;
if not argType.isMatchForVariable() then begin
raise CompileError.create(msgTypeNotApplicableToVar, lexemes, position);
end;
if lexemes.getType(position) <> TranslatorLexer.IDENTIFIER then begin
raise CompileError.create(msgExpectedIdentifierOfArgument,
lexemes, position);
end;
argName := lexemes.getValueUString(position);
if destination.findArgument(argName) <> nil then begin
raise CompileError.create(msgAlreadyExistsIdentifier, lexemes, position);
end;
argument := destination.addArgument(argType, argName);
argument.declarePosition := position;
inc(position);
if lexemes.getType(position) <> TranslatorLexer.COMMA then begin
break;
end;
inc(position);
until false;
end;
result := position;
end;
function TranslatorNamespacesBuilder.parseConstElem(where: Namespace; lexemes: Lexer;
position: int): GlobalConstant;
var
i: int;
kind: int;
value: int;
compound: GlobalConstant_Array1d;
index: GlobalConstant;
place: Namespace;
entry: NamespaceEntry;
ident: UnicodeString;
begin
case lexemes.getType(position) of
TranslatorLexer.OPENED_PARENTHESIS: begin
result := parseConstCond(where, lexemes, position + 1);
position := stayPosition;
if lexemes.getType(position) <> TranslatorLexer.CLOSED_PARENTHESIS then begin
raise CompileError.create(msgExpectedClosedParenthesis, lexemes, position);
end;
end;
TranslatorLexer.IDENTIFIER: begin
ident := lexemes.getValueUString(position);
entry := where.findEntry(ident, true);
if entry = nil then begin
place := findNamespace(ident);
if place = nil then begin
raise CompileError.create(msgExpectedConstant, lexemes, position);
end;
inc(position);
if lexemes.getType(position) <> TranslatorLexer.PERIOD then begin
raise CompileError.create(msgExpectedPeriod, lexemes, position);
end;
inc(position);
if lexemes.getType(position) <> TranslatorLexer.IDENTIFIER then begin
raise CompileError.create(msgExpectedIdentifierOfConstant, lexemes, position);
end;
ident := lexemes.getValueUString(position);
entry := place.findEntry(ident, false);
if not (entry is GlobalConstant) or not where.isVisible(entry) then begin
raise CompileError.create(msgExpectedIdentifierOfConstant, lexemes, position);
end;
result := entry as GlobalConstant;
end else
if entry is GlobalConstant then begin
result := entry as GlobalConstant;
end else begin
raise CompileError.create(msgExpectedIdentifierOfConstant, lexemes, position);
end;
end;
TranslatorLexer.KW_FALSE: begin
result := TranslatorLocalConstantInt.create(typeBoolean, false);
end;
TranslatorLexer.KW_TRUE: begin
result := TranslatorLocalConstantInt.create(typeBoolean, true);
end;
TranslatorLexer.KW_NEW: begin
inc(position);
if operandSize < TranslatorType.SIZE_64_BIT then begin
raise CompileError.create(msgTypeNotSupported, lexemes, position);
end;
case lexemes.getType(position) of
TranslatorLexer.KW_ULTRA: begin
inc(position);
if lexemes.getType(position) <> TranslatorLexer.OPENED_CURLY_BRACKET then begin
raise CompileError.create(msgExpectedOpenedCurlyBracket, lexemes, position);
end;
inc(position);
compound := GlobalConstant_Array1d(Interface_Array1d_create(4));
for i := 0 to 3 do begin
compound[i] := parseConstCond(where, lexemes, position);
position := stayPosition;
if not possibleAssign(TranslatorType.KIND_INT, compound[i]) then begin
raise CompileError.create(msgCannotAssignDataType, lexemes, position);
end;
if i < 3 then begin
if lexemes.getType(position) <> TranslatorLexer.COMMA then begin
raise CompileError.create(msgExpectedComma, lexemes, position);
end;
inc(position);
end;
end;
result := TranslatorLocalConstantUltra.create(typeUltra, ultraBuild(
compound[3].intValue, compound[2].intValue,
compound[1].intValue, compound[0].intValue));
end;
TranslatorLexer.KW_XVECTOR: begin
inc(position);
if lexemes.getType(position) <> TranslatorLexer.OPENED_CURLY_BRACKET then begin
raise CompileError.create(msgExpectedOpenedCurlyBracket, lexemes, position);
end;
inc(position);
compound := GlobalConstant_Array1d(Interface_Array1d_create(4));
for i := 0 to 3 do begin
compound[i] := parseConstCond(where, lexemes, position);
position := stayPosition;
if not possibleAssign(TranslatorType.KIND_FLOAT, compound[i]) then begin
raise CompileError.create(msgCannotAssignDataType, lexemes, position);
end;
if i < 3 then begin
if lexemes.getType(position) <> TranslatorLexer.COMMA then begin
raise CompileError.create(msgExpectedComma, lexemes, position);
end;
inc(position);
end;
end;
result := TranslatorLocalConstantXVector.create(typeXVector, xvectorBuild(
compound[3].realValue, compound[2].realValue,
compound[1].realValue, compound[0].realValue));
end;
TranslatorLexer.KW_YVECTOR, TranslatorLexer.KW_ULTRA32,
TranslatorLexer.KW_ZVECTOR, TranslatorLexer.KW_ULTRA64,
TranslatorLexer.KW_FVECTOR: begin
raise CompileError.create(msgTypeReserved, lexemes, position);
end;
else
raise CompileError.create(msgExpectedDataTypeCompound, lexemes, position);
end;
if lexemes.getType(position) <> TranslatorLexer.CLOSED_CURLY_BRACKET then begin
raise CompileError.create(msgExpectedClosedCurlyBracket, lexemes, position);
end;
end;
TranslatorLexer.NUM_INT: begin
value := lexemes.getValueInt(position);
if operandSize < TranslatorType.SIZE_32_BIT then begin
if (value < -$8000) or (value > $ffff) then begin
raise CompileError.create(msgTypeNotSupported, lexemes, position);
end;
if value < $8000 then begin
result := TranslatorLocalConstantInt.create(typeShort, value);
end else begin
result := TranslatorLocalConstantInt.create(typeChar, value);
end;
end else begin
result := TranslatorLocalConstantInt.create(typeInt, value);
end;
end;
TranslatorLexer.NUM_LONG: begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
raise CompileError.create(msgTypeNotSupported, lexemes, position);
end;
result := TranslatorLocalConstantLong.create(typeLong, lexemes.getValueLong(position));
end;
TranslatorLexer.NUM_FLOAT: begin
result := TranslatorLocalConstantReal.create(typeFloat, lexemes.getValueReal(position));
end;
TranslatorLexer.NUM_DOUBLE: begin
result := TranslatorLocalConstantReal.create(typeDouble, lexemes.getValueReal(position));
end;
TranslatorLexer.NUM_REAL: begin
result := TranslatorLocalConstantReal.create(typeReal, lexemes.getValueReal(position));
end;
else
raise CompileError.create(msgExpressionError, lexemes, position);
end;
inc(position);
if lexemes.getType(position) = TranslatorLexer.OPENED_SQUARE_BRACKET then begin
kind := result.dataType.kind;
case kind of
TranslatorType.KIND_ULTRA, TranslatorType.KIND_XVECTOR: ;
else
raise CompileError.create(msgTypeMustBeCompound, lexemes, position);
end;
index := parseConstCond(where, lexemes, position + 1);
position := stayPosition;
if not possibleAssign(TranslatorType.KIND_INT, index) then begin
raise CompileError.create(msgTypeMustBeInt, lexemes, position);
end;
i := index.intValue;
if (i < 0) or (i >= 4) then begin
raise CompileError.create(msgCompoundIndexOutOfBounds, lexemes, position);
end;
if lexemes.getType(position) <> TranslatorLexer.CLOSED_SQUARE_BRACKET then begin
raise CompileError.create(msgExpectedClosedSquareBracket, lexemes, position);
end;
case kind of
TranslatorType.KIND_ULTRA:
result := TranslatorLocalConstantInt.create(typeInt,
result.getUltraValue().ints[i]);
TranslatorType.KIND_XVECTOR:
result := TranslatorLocalConstantReal.create(typeFloat,
result.getXVectorValue().floats[i]);
end;
inc(position);
end;
stayPosition := position;
end;
function TranslatorNamespacesBuilder.parseConstPref(where: Namespace; lexemes: Lexer;
position: int): GlobalConstant;
var
endPosition: int;
typeForCast: TypeDescriptor;
begin
case lexemes.getType(position) of
TranslatorLexer.OPENED_PARENTHESIS: begin
inc(position);
typeForCast := tryParseType(where, position);
endPosition := stayPosition;
if (typeForCast <> nil) and
(lexemes.getType(endPosition) = TranslatorLexer.CLOSED_PARENTHESIS) then begin
if not typeForCast.isMatchForConstant() then begin
raise CompileError.create(msgTypeNotApplicableToConst, lexemes, position);
end;
result := parseConstPref(where, lexemes, endPosition + 1);
if not result.dataType.possibleCastTo(typeForCast) then begin
raise CompileError.create(msgCannotCastToType, lexemes, position);
end;
result := castConstTo(typeForCast.kind, result);
end else begin
result := parseConstElem(where, lexemes, position - 1);
end;
end;
TranslatorLexer.SNOTB: begin
result := parseConstPref(where, lexemes, position + 1);
case result.dataType.kind of
TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE,
TranslatorType.KIND_SHORT, TranslatorType.KIND_INT:
if operandSize < TranslatorType.SIZE_32_BIT then begin
result := TranslatorLocalConstantInt.create(typeShort,
short(result.shortValue xor (-1)));
end else begin
result := TranslatorLocalConstantInt.create(typeInt,
result.intValue xor (-1));
end;
TranslatorType.KIND_LONG:
result := TranslatorLocalConstantLong.create(typeLong,
result.longValue xor (-1));
TranslatorType.KIND_ULTRA:
result := TranslatorLocalConstantUltra.create(typeUltra,
result.getUltraValue() xor ultraBuild(-1, -1));
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.SNOTL: begin
result := parseConstPref(where, lexemes, position + 1);
if result.dataType.kind = TranslatorType.KIND_BOOLEAN then begin
result := TranslatorLocalConstantInt.create(typeBoolean,
not result.booleanValue);
end else begin
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.SPLUS: begin
result := parseConstPref(where, lexemes, position + 1);
case result.dataType.kind of
TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE,
TranslatorType.KIND_SHORT, TranslatorType.KIND_INT:
if operandSize < TranslatorType.SIZE_32_BIT then begin
result := TranslatorLocalConstantInt.create(typeShort,
result.shortValue);
end else begin
result := TranslatorLocalConstantInt.create(typeInt,
result.intValue);
end;
TranslatorType.KIND_LONG:
result := TranslatorLocalConstantLong.create(typeLong,
result.longValue);
TranslatorType.KIND_FLOAT:
result := TranslatorLocalConstantReal.create(typeFloat,
result.realValue);
TranslatorType.KIND_DOUBLE:
result := TranslatorLocalConstantReal.create(typeDouble,
result.realValue);
TranslatorType.KIND_REAL:
result := TranslatorLocalConstantReal.create(typeReal,
result.realValue);
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.SMINUS: begin
result := parseConstPref(where, lexemes, position + 1);
case result.dataType.kind of
TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE,
TranslatorType.KIND_SHORT, TranslatorType.KIND_INT:
if operandSize < TranslatorType.SIZE_32_BIT then begin
result := TranslatorLocalConstantInt.create(typeShort,
short(-result.shortValue));
end else begin
result := TranslatorLocalConstantInt.create(typeInt,
-result.intValue);
end;
TranslatorType.KIND_LONG:
result := TranslatorLocalConstantLong.create(typeLong,
-result.longValue);
TranslatorType.KIND_FLOAT:
result := TranslatorLocalConstantReal.create(typeFloat,
-result.realValue);
TranslatorType.KIND_DOUBLE:
result := TranslatorLocalConstantReal.create(typeDouble,
-result.realValue);
TranslatorType.KIND_REAL:
result := TranslatorLocalConstantReal.create(typeReal,
-result.realValue);
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.QPACKUS: begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
end;
result := parseConstPref(where, lexemes, position + 1);
case result.dataType.kind of
TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE, TranslatorType.KIND_SHORT,
TranslatorType.KIND_INT, TranslatorType.KIND_LONG:
result := TranslatorLocalConstantInt.create(typeInt,
mmxPack(result.longValue));
TranslatorType.KIND_ULTRA: begin
if extension < EXTENSION_SSE4_1 then begin
raise CompileError.create(msgOperationNotSupportedEX, lexemes, position);
end;
result := TranslatorLocalConstantLong.create(typeLong,
pack4IntUS(result.getUltraValue()));
end;
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.QUNPCKL: begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
end;
result := parseConstPref(where, lexemes, position + 1);
case result.dataType.kind of
TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE,
TranslatorType.KIND_SHORT, TranslatorType.KIND_INT:
result := TranslatorLocalConstantLong.create(typeLong,
mmxUnpackLo(result.intValue));
TranslatorType.KIND_LONG:
result := TranslatorLocalConstantUltra.create(typeUltra,
sseiUnpackLo(result.longValue));
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.QUNPCKH: begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
end;
result := parseConstPref(where, lexemes, position + 1);
case result.dataType.kind of
TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE,
TranslatorType.KIND_SHORT, TranslatorType.KIND_INT:
result := TranslatorLocalConstantLong.create(typeLong,
mmxUnpackHi(result.intValue));
TranslatorType.KIND_LONG:
result := TranslatorLocalConstantUltra.create(typeUltra,
sseiUnpackHi(result.longValue));
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.QADD: begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
end;
result := parseConstPref(where, lexemes, position + 1);
case result.dataType.kind of
TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE,
TranslatorType.KIND_SHORT, TranslatorType.KIND_INT:
result := TranslatorLocalConstantLong.create(typeLong, result.longValue);
TranslatorType.KIND_FLOAT:
result := TranslatorLocalConstantXVector.create(typeXVector, result.getXVectorValue());
TranslatorType.KIND_LONG, TranslatorType.KIND_ULTRA, TranslatorType.KIND_XVECTOR: ;
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.QSUB: begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
end;
result := parseConstPref(where, lexemes, position + 1);
case result.dataType.kind of
TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE, TranslatorType.KIND_SHORT,
TranslatorType.KIND_INT, TranslatorType.KIND_LONG:
result := TranslatorLocalConstantLong.create(typeLong,
mmxSub(0, result.longValue));
TranslatorType.KIND_ULTRA:
result := TranslatorLocalConstantUltra.create(typeUltra,
sseiSub(ultraBuild(0, 0, 0, 0), result.getUltraValue()));
TranslatorType.KIND_FLOAT, TranslatorType.KIND_XVECTOR:
result := TranslatorLocalConstantXVector.create(typeXVector,
ssefSub(xvectorBuild(0, 0, 0, 0), result.getXVectorValue()));
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.OPACKUS: begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
end;
result := parseConstPref(where, lexemes, position + 1);
case result.dataType.kind of
TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE, TranslatorType.KIND_SHORT,
TranslatorType.KIND_INT, TranslatorType.KIND_LONG, TranslatorType.KIND_ULTRA: begin
result := TranslatorLocalConstantLong.create(typeLong,
ssesPack(result.getUltraValue()));
end;
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.OUNPCKL: begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
end;
result := parseConstPref(where, lexemes, position + 1);
case result.dataType.kind of
TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE, TranslatorType.KIND_SHORT,
TranslatorType.KIND_INT, TranslatorType.KIND_LONG:
result := TranslatorLocalConstantUltra.create(typeUltra,
ssesUnpackLo(result.longValue));
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.OUNPCKH: begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
end;
result := parseConstPref(where, lexemes, position + 1);
case result.dataType.kind of
TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE, TranslatorType.KIND_SHORT,
TranslatorType.KIND_INT, TranslatorType.KIND_LONG:
result := TranslatorLocalConstantUltra.create(typeUltra,
ssesUnpackHi(result.longValue));
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.OADD: begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
end;
result := parseConstPref(where, lexemes, position + 1);
case result.dataType.kind of
TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE, TranslatorType.KIND_SHORT,
TranslatorType.KIND_INT, TranslatorType.KIND_LONG:
result := TranslatorLocalConstantUltra.create(typeUltra, result.getUltraValue());
TranslatorType.KIND_ULTRA: ;
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.OSUB: begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
end;
result := parseConstPref(where, lexemes, position + 1);
case result.dataType.kind of
TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE, TranslatorType.KIND_SHORT,
TranslatorType.KIND_INT, TranslatorType.KIND_LONG, TranslatorType.KIND_ULTRA:
result := TranslatorLocalConstantUltra.create(typeUltra,
ssesSub(ultraBuild(0, 0, 0, 0), result.getUltraValue()));
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
else
result := parseConstElem(where, lexemes, position);
end;
end;
function TranslatorNamespacesBuilder.parseConstMult(where: Namespace; lexemes: Lexer;
position: int): GlobalConstant;
var
ival: int;
lval: long;
second: GlobalConstant;
begin
result := parseConstPref(where, lexemes, position);
repeat
position := stayPosition;
case lexemes.getType(position) of
TranslatorLexer.SMULL: begin
second := parseConstPref(where, lexemes, position + 1);
case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
TranslatorType.KIND_SHORT:
result := TranslatorLocalConstantInt.create(typeShort,
short(result.shortValue * second.shortValue));
TranslatorType.KIND_INT:
result := TranslatorLocalConstantInt.create(typeInt,
result.intValue * second.intValue);
TranslatorType.KIND_LONG:
result := TranslatorLocalConstantLong.create(typeLong,
long(result.longValue) * long(second.longValue));
TranslatorType.KIND_FLOAT:
result := TranslatorLocalConstantReal.create(typeFloat,
result.realValue * second.realValue);
TranslatorType.KIND_DOUBLE:
result := TranslatorLocalConstantReal.create(typeDouble,
result.realValue * second.realValue);
TranslatorType.KIND_REAL:
result := TranslatorLocalConstantReal.create(typeReal,
result.realValue * second.realValue);
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.SDIVS: begin
second := parseConstPref(where, lexemes, position + 1);
case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
TranslatorType.KIND_SHORT: begin
ival := second.shortValue;
if ival = 0 then begin
raise CompileError.create(msgIntegerDivisionByZero, lexemes, position);
end;
result := TranslatorLocalConstantInt.create(typeShort,
short(result.shortValue div ival));
end;
TranslatorType.KIND_INT: begin
ival := second.intValue;
if ival = 0 then begin
raise CompileError.create(msgIntegerDivisionByZero, lexemes, position);
end;
result := TranslatorLocalConstantInt.create(typeInt,
result.intValue div ival);
end;
TranslatorType.KIND_LONG: begin
lval := second.longValue;
if lval = 0 then begin
raise CompileError.create(msgIntegerDivisionByZero, lexemes, position);
end;
result := TranslatorLocalConstantLong.create(typeLong,
long(result.longValue) div lval);
end;
TranslatorType.KIND_FLOAT:
result := TranslatorLocalConstantReal.create(typeFloat,
result.realValue / second.realValue);
TranslatorType.KIND_DOUBLE:
result := TranslatorLocalConstantReal.create(typeDouble,
result.realValue / second.realValue);
TranslatorType.KIND_REAL:
result := TranslatorLocalConstantReal.create(typeReal,
result.realValue / second.realValue);
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.SREMS: begin
second := parseConstPref(where, lexemes, position + 1);
case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
TranslatorType.KIND_SHORT: begin
ival := second.shortValue;
if ival = 0 then begin
raise CompileError.create(msgIntegerDivisionByZero, lexemes, position);
end;
result := TranslatorLocalConstantInt.create(typeShort,
short(result.shortValue mod ival));
end;
TranslatorType.KIND_INT: begin
ival := second.intValue;
if ival = 0 then begin
raise CompileError.create(msgIntegerDivisionByZero, lexemes, position);
end;
result := TranslatorLocalConstantInt.create(typeInt,
result.intValue mod ival);
end;
TranslatorType.KIND_LONG: begin
lval := second.longValue;
if lval = 0 then begin
raise CompileError.create(msgIntegerDivisionByZero, lexemes, position);
end;
result := TranslatorLocalConstantLong.create(typeLong,
long(result.longValue) mod lval);
end;
TranslatorType.KIND_FLOAT:
result := TranslatorLocalConstantReal.create(typeFloat,
realMod(result.realValue, second.realValue));
TranslatorType.KIND_DOUBLE:
result := TranslatorLocalConstantReal.create(typeDouble,
realMod(result.realValue, second.realValue));
TranslatorType.KIND_REAL:
result := TranslatorLocalConstantReal.create(typeReal,
realMod(result.realValue, second.realValue));
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.SDIVU: begin
second := parseConstPref(where, lexemes, position + 1);
case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
TranslatorType.KIND_SHORT: begin
ival := second.charValue;
if ival = 0 then begin
raise CompileError.create(msgIntegerDivisionByZero, lexemes, position);
end;
result := TranslatorLocalConstantInt.create(typeShort,
short(result.charValue div ival));
end;
TranslatorType.KIND_INT: begin
ival := second.intValue;
if ival = 0 then begin
raise CompileError.create(msgIntegerDivisionByZero, lexemes, position);
end;
result := TranslatorLocalConstantInt.create(typeInt,
intUDiv(result.intValue, ival));
end;
TranslatorType.KIND_LONG: begin
lval := second.longValue;
if lval = 0 then begin
raise CompileError.create(msgIntegerDivisionByZero, lexemes, position);
end;
result := TranslatorLocalConstantLong.create(typeLong,
longUDiv(result.longValue, lval));
end;
TranslatorType.KIND_FLOAT:
result := TranslatorLocalConstantReal.create(typeFloat,
result.realValue / second.realValue);
TranslatorType.KIND_DOUBLE:
result := TranslatorLocalConstantReal.create(typeDouble,
result.realValue / second.realValue);
TranslatorType.KIND_REAL:
result := TranslatorLocalConstantReal.create(typeReal,
result.realValue / second.realValue);
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.SREMU: begin
second := parseConstPref(where, lexemes, position + 1);
case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
TranslatorType.KIND_SHORT: begin
ival := second.charValue;
if ival = 0 then begin
raise CompileError.create(msgIntegerDivisionByZero, lexemes, position);
end;
result := TranslatorLocalConstantInt.create(typeShort,
short(result.charValue mod ival));
end;
TranslatorType.KIND_INT: begin
ival := second.intValue;
if ival = 0 then begin
raise CompileError.create(msgIntegerDivisionByZero, lexemes, position);
end;
result := TranslatorLocalConstantInt.create(typeInt,
intUMod(result.intValue, ival));
end;
TranslatorType.KIND_LONG: begin
lval := second.longValue;
if lval = 0 then begin
raise CompileError.create(msgIntegerDivisionByZero, lexemes, position);
end;
result := TranslatorLocalConstantLong.create(typeLong,
longUMod(result.longValue, lval));
end;
TranslatorType.KIND_FLOAT:
result := TranslatorLocalConstantReal.create(typeFloat,
realMod(result.realValue, second.realValue));
TranslatorType.KIND_DOUBLE:
result := TranslatorLocalConstantReal.create(typeDouble,
realMod(result.realValue, second.realValue));
TranslatorType.KIND_REAL:
result := TranslatorLocalConstantReal.create(typeReal,
realMod(result.realValue, second.realValue));
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.QMULL: begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
end;
second := parseConstPref(where, lexemes, position + 1);
case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
TranslatorType.KIND_INT, TranslatorType.KIND_LONG:
result := TranslatorLocalConstantLong.create(typeLong,
mmxMulLo(result.longValue, second.longValue));
TranslatorType.KIND_ULTRA:
result := TranslatorLocalConstantUltra.create(typeUltra,
sseiMulLo(result.getUltraValue(), second.getUltraValue()));
TranslatorType.KIND_FLOAT, TranslatorType.KIND_XVECTOR:
result := TranslatorLocalConstantXVector.create(typeXVector,
ssefMul(result.getXVectorValue(), second.getXVectorValue()));
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.QMULH: begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
end;
second := parseConstPref(where, lexemes, position + 1);
case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
TranslatorType.KIND_INT, TranslatorType.KIND_LONG:
result := TranslatorLocalConstantLong.create(typeLong,
mmxMulHi(result.longValue, second.longValue));
TranslatorType.KIND_ULTRA:
result := TranslatorLocalConstantUltra.create(typeUltra,
sseiMulHi(result.getUltraValue(), second.getUltraValue()));
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.QMULHS: begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
end;
second := parseConstPref(where, lexemes, position + 1);
case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
TranslatorType.KIND_INT, TranslatorType.KIND_LONG:
result := TranslatorLocalConstantLong.create(typeLong,
mmxMulHiS(result.longValue, second.longValue));
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.QDIV: begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
end;
second := parseConstPref(where, lexemes, position + 1);
case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
TranslatorType.KIND_FLOAT, TranslatorType.KIND_XVECTOR:
result := TranslatorLocalConstantXVector.create(typeXVector,
ssefDiv(result.getXVectorValue(), second.getXVectorValue()));
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.OMULL: begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
end;
second := parseConstPref(where, lexemes, position + 1);
case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
TranslatorType.KIND_INT, TranslatorType.KIND_LONG, TranslatorType.KIND_ULTRA:
result := TranslatorLocalConstantUltra.create(typeUltra,
ssesMulLo(result.getUltraValue(), second.getUltraValue()));
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.OMULH: begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
end;
second := parseConstPref(where, lexemes, position + 1);
case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
TranslatorType.KIND_INT, TranslatorType.KIND_LONG, TranslatorType.KIND_ULTRA:
result := TranslatorLocalConstantUltra.create(typeUltra,
ssesMulHi(result.getUltraValue(), second.getUltraValue()));
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.OMULHS: begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
end;
second := parseConstPref(where, lexemes, position + 1);
case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
TranslatorType.KIND_INT, TranslatorType.KIND_LONG, TranslatorType.KIND_ULTRA:
result := TranslatorLocalConstantUltra.create(typeUltra,
ssesMulHiS(result.getUltraValue(), second.getUltraValue()));
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
else
break;
end;
until false;
end;
function TranslatorNamespacesBuilder.parseConstAdd(where: Namespace; lexemes: Lexer;
position: int): GlobalConstant;
var
second: GlobalConstant;
begin
result := parseConstMult(where, lexemes, position);
repeat
position := stayPosition;
case lexemes.getType(position) of
TranslatorLexer.SPLUS: begin
second := parseConstMult(where, lexemes, position + 1);
case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
TranslatorType.KIND_SHORT:
result := TranslatorLocalConstantInt.create(typeShort,
short(result.shortValue + second.shortValue));
TranslatorType.KIND_INT:
result := TranslatorLocalConstantInt.create(typeInt,
result.intValue + second.intValue);
TranslatorType.KIND_LONG:
result := TranslatorLocalConstantLong.create(typeLong,
result.longValue + second.longValue);
TranslatorType.KIND_FLOAT:
result := TranslatorLocalConstantReal.create(typeFloat,
result.realValue + second.realValue);
TranslatorType.KIND_DOUBLE:
result := TranslatorLocalConstantReal.create(typeDouble,
result.realValue + second.realValue);
TranslatorType.KIND_REAL:
result := TranslatorLocalConstantReal.create(typeReal,
result.realValue + second.realValue);
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.SMINUS: begin
second := parseConstMult(where, lexemes, position + 1);
case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
TranslatorType.KIND_SHORT:
result := TranslatorLocalConstantInt.create(typeShort,
short(result.shortValue - second.shortValue));
TranslatorType.KIND_INT:
result := TranslatorLocalConstantInt.create(typeInt,
result.intValue - second.intValue);
TranslatorType.KIND_LONG:
result := TranslatorLocalConstantLong.create(typeLong,
result.longValue - second.longValue);
TranslatorType.KIND_FLOAT:
result := TranslatorLocalConstantReal.create(typeFloat,
result.realValue - second.realValue);
TranslatorType.KIND_DOUBLE:
result := TranslatorLocalConstantReal.create(typeDouble,
result.realValue - second.realValue);
TranslatorType.KIND_REAL:
result := TranslatorLocalConstantReal.create(typeReal,
result.realValue - second.realValue);
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.QADD: begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
end;
second := parseConstMult(where, lexemes, position + 1);
case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
TranslatorType.KIND_INT, TranslatorType.KIND_LONG:
result := TranslatorLocalConstantLong.create(typeLong,
mmxAdd(result.longValue, second.longValue));
TranslatorType.KIND_ULTRA:
result := TranslatorLocalConstantUltra.create(typeUltra,
sseiAdd(result.getUltraValue(), second.getUltraValue()));
TranslatorType.KIND_FLOAT, TranslatorType.KIND_XVECTOR:
result := TranslatorLocalConstantXVector.create(typeXVector,
ssefAdd(result.getXVectorValue(), second.getXVectorValue()));
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.QADDS: begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
end;
second := parseConstMult(where, lexemes, position + 1);
case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
TranslatorType.KIND_INT, TranslatorType.KIND_LONG:
result := TranslatorLocalConstantLong.create(typeLong,
mmxAddS(result.longValue, second.longValue));
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.QADDUS: begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
end;
second := parseConstMult(where, lexemes, position + 1);
case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
TranslatorType.KIND_INT, TranslatorType.KIND_LONG:
result := TranslatorLocalConstantLong.create(typeLong,
mmxAddUS(result.longValue, second.longValue));
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.QSUB: begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
end;
second := parseConstMult(where, lexemes, position + 1);
case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
TranslatorType.KIND_INT, TranslatorType.KIND_LONG:
result := TranslatorLocalConstantLong.create(typeLong,
mmxSub(result.longValue, second.longValue));
TranslatorType.KIND_ULTRA:
result := TranslatorLocalConstantUltra.create(typeUltra,
sseiSub(result.getUltraValue(), second.getUltraValue()));
TranslatorType.KIND_FLOAT, TranslatorType.KIND_XVECTOR:
result := TranslatorLocalConstantXVector.create(typeXVector,
ssefSub(result.getXVectorValue(), second.getXVectorValue()));
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.QSUBS: begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
end;
second := parseConstMult(where, lexemes, position + 1);
case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
TranslatorType.KIND_INT, TranslatorType.KIND_LONG:
result := TranslatorLocalConstantLong.create(typeLong,
mmxSubS(result.longValue, second.longValue));
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.QSUBUS: begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
end;
second := parseConstMult(where, lexemes, position + 1);
case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
TranslatorType.KIND_INT, TranslatorType.KIND_LONG:
result := TranslatorLocalConstantLong.create(typeLong,
mmxSubUS(result.longValue, second.longValue));
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.OADD: begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
end;
second := parseConstMult(where, lexemes, position + 1);
case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
TranslatorType.KIND_INT, TranslatorType.KIND_LONG, TranslatorType.KIND_ULTRA:
result := TranslatorLocalConstantUltra.create(typeUltra,
ssesAdd(result.getUltraValue(), second.getUltraValue()));
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.OADDS: begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
end;
second := parseConstMult(where, lexemes, position + 1);
case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
TranslatorType.KIND_INT, TranslatorType.KIND_LONG, TranslatorType.KIND_ULTRA:
result := TranslatorLocalConstantUltra.create(typeUltra,
ssesAddS(result.getUltraValue(), second.getUltraValue()));
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.OADDUS: begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
end;
second := parseConstMult(where, lexemes, position + 1);
case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
TranslatorType.KIND_INT, TranslatorType.KIND_LONG, TranslatorType.KIND_ULTRA:
result := TranslatorLocalConstantUltra.create(typeUltra,
ssesAddUS(result.getUltraValue(), second.getUltraValue()));
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.OSUB: begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
end;
second := parseConstMult(where, lexemes, position + 1);
case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
TranslatorType.KIND_INT, TranslatorType.KIND_LONG, TranslatorType.KIND_ULTRA:
result := TranslatorLocalConstantUltra.create(typeUltra,
ssesSub(result.getUltraValue(), second.getUltraValue()));
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.OSUBS: begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
end;
second := parseConstMult(where, lexemes, position + 1);
case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
TranslatorType.KIND_INT, TranslatorType.KIND_LONG, TranslatorType.KIND_ULTRA:
result := TranslatorLocalConstantUltra.create(typeUltra,
ssesSubS(result.getUltraValue(), second.getUltraValue()));
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.OSUBUS: begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
end;
second := parseConstMult(where, lexemes, position + 1);
case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
TranslatorType.KIND_INT, TranslatorType.KIND_LONG, TranslatorType.KIND_ULTRA:
result := TranslatorLocalConstantUltra.create(typeUltra,
ssesSubUS(result.getUltraValue(), second.getUltraValue()));
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
else
break;
end;
until false;
end;
function TranslatorNamespacesBuilder.parseConstShift(where: Namespace; lexemes: Lexer;
position: int): GlobalConstant;
var
second: GlobalConstant;
begin
result := parseConstAdd(where, lexemes, position);
repeat
position := stayPosition;
case lexemes.getType(position) of
TranslatorLexer.SSLL: begin
second := parseConstAdd(where, lexemes, position + 1);
if not possibleAssign(TranslatorType.KIND_INT, second) then begin
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
case result.dataType.kind of
TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE,
TranslatorType.KIND_SHORT, TranslatorType.KIND_INT:
if operandSize < TranslatorType.SIZE_32_BIT then begin
result := TranslatorLocalConstantInt.create(typeShort,
short(result.shortValue shl second.intValue));
end else begin
result := TranslatorLocalConstantInt.create(typeInt,
result.intValue shl second.intValue);
end;
TranslatorType.KIND_LONG:
result := TranslatorLocalConstantLong.create(typeLong,
long(result.longValue) shl second.intValue);
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.SSRA: begin
second := parseConstAdd(where, lexemes, position + 1);
if not possibleAssign(TranslatorType.KIND_INT, second) then begin
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
case result.dataType.kind of
TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE,
TranslatorType.KIND_SHORT, TranslatorType.KIND_INT:
if operandSize < TranslatorType.SIZE_32_BIT then begin
result := TranslatorLocalConstantInt.create(typeShort,
short(intSar(result.shortValue, second.intValue)));
end else begin
result := TranslatorLocalConstantInt.create(typeInt,
intSar(result.intValue, second.intValue));
end;
TranslatorType.KIND_LONG:
result := TranslatorLocalConstantLong.create(typeLong,
longSar(result.longValue, second.intValue));
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.SSRL: begin
second := parseConstAdd(where, lexemes, position + 1);
if not possibleAssign(TranslatorType.KIND_INT, second) then begin
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
case result.dataType.kind of
TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE,
TranslatorType.KIND_SHORT, TranslatorType.KIND_INT:
if operandSize < TranslatorType.SIZE_32_BIT then begin
result := TranslatorLocalConstantInt.create(typeShort,
short((result.shortValue and $ffff) shr second.intValue));
end else begin
result := TranslatorLocalConstantInt.create(typeInt,
result.intValue shr second.intValue);
end;
TranslatorType.KIND_LONG:
result := TranslatorLocalConstantLong.create(typeLong,
long(result.longValue) shr second.intValue);
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.QSLL: begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
end;
second := parseConstAdd(where, lexemes, position + 1);
if not possibleAssign(TranslatorType.KIND_INT, second) then begin
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
case result.dataType.kind of
TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE, TranslatorType.KIND_SHORT,
TranslatorType.KIND_INT, TranslatorType.KIND_LONG:
result := TranslatorLocalConstantLong.create(typeLong,
mmxShl(result.longValue, second.intValue));
TranslatorType.KIND_ULTRA:
result := TranslatorLocalConstantUltra.create(typeUltra,
sseiShl(result.getUltraValue(), second.intValue));
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.QSRA: begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
end;
second := parseConstAdd(where, lexemes, position + 1);
if not possibleAssign(TranslatorType.KIND_INT, second) then begin
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
case result.dataType.kind of
TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE, TranslatorType.KIND_SHORT,
TranslatorType.KIND_INT, TranslatorType.KIND_LONG:
result := TranslatorLocalConstantLong.create(typeLong,
mmxSar(result.longValue, second.intValue));
TranslatorType.KIND_ULTRA:
result := TranslatorLocalConstantUltra.create(typeUltra,
sseiSar(result.getUltraValue(), second.intValue));
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.QSRL: begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
end;
second := parseConstAdd(where, lexemes, position + 1);
if not possibleAssign(TranslatorType.KIND_INT, second) then begin
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
case result.dataType.kind of
TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE, TranslatorType.KIND_SHORT,
TranslatorType.KIND_INT, TranslatorType.KIND_LONG:
result := TranslatorLocalConstantLong.create(typeLong,
mmxShr(result.longValue, second.intValue));
TranslatorType.KIND_ULTRA:
result := TranslatorLocalConstantUltra.create(typeUltra,
sseiShr(result.getUltraValue(), second.intValue));
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.OSLL: begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
end;
second := parseConstAdd(where, lexemes, position + 1);
if not possibleAssign(TranslatorType.KIND_INT, second) then begin
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
case result.dataType.kind of
TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE, TranslatorType.KIND_SHORT,
TranslatorType.KIND_INT, TranslatorType.KIND_LONG, TranslatorType.KIND_ULTRA:
result := TranslatorLocalConstantUltra.create(typeUltra,
ssesShl(result.getUltraValue(), second.intValue));
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.OSRA: begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
end;
second := parseConstAdd(where, lexemes, position + 1);
if not possibleAssign(TranslatorType.KIND_INT, second) then begin
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
case result.dataType.kind of
TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE, TranslatorType.KIND_SHORT,
TranslatorType.KIND_INT, TranslatorType.KIND_LONG, TranslatorType.KIND_ULTRA:
result := TranslatorLocalConstantUltra.create(typeUltra,
ssesSar(result.getUltraValue(), second.intValue));
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.OSRL: begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
end;
second := parseConstAdd(where, lexemes, position + 1);
if not possibleAssign(TranslatorType.KIND_INT, second) then begin
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
case result.dataType.kind of
TranslatorType.KIND_CHAR, TranslatorType.KIND_BYTE, TranslatorType.KIND_SHORT,
TranslatorType.KIND_INT, TranslatorType.KIND_LONG, TranslatorType.KIND_ULTRA:
result := TranslatorLocalConstantUltra.create(typeUltra,
ssesShr(result.getUltraValue(), second.intValue));
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
else
break;
end;
until false;
end;
function TranslatorNamespacesBuilder.parseConstRel(where: Namespace; lexemes: Lexer;
position: int): GlobalConstant;
var
second: GlobalConstant;
begin
result := parseConstShift(where, lexemes, position);
repeat
position := stayPosition;
case lexemes.getType(position) of
TranslatorLexer.SGT: begin
second := parseConstShift(where, lexemes, position + 1);
case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
TranslatorType.KIND_SHORT:
result := TranslatorLocalConstantInt.create(typeBoolean,
result.shortValue > second.shortValue);
TranslatorType.KIND_INT:
result := TranslatorLocalConstantInt.create(typeBoolean,
result.intValue > second.intValue);
TranslatorType.KIND_LONG:
result := TranslatorLocalConstantInt.create(typeBoolean,
result.longValue > second.longValue);
TranslatorType.KIND_FLOAT, TranslatorType.KIND_DOUBLE, TranslatorType.KIND_REAL:
result := TranslatorLocalConstantInt.create(typeBoolean,
realCmpl(result.realValue, second.realValue) > 0);
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.SGE: begin
second := parseConstShift(where, lexemes, position + 1);
case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
TranslatorType.KIND_SHORT:
result := TranslatorLocalConstantInt.create(typeBoolean,
result.shortValue >= second.shortValue);
TranslatorType.KIND_INT:
result := TranslatorLocalConstantInt.create(typeBoolean,
result.intValue >= second.intValue);
TranslatorType.KIND_LONG:
result := TranslatorLocalConstantInt.create(typeBoolean,
result.longValue >= second.longValue);
TranslatorType.KIND_FLOAT, TranslatorType.KIND_DOUBLE, TranslatorType.KIND_REAL:
result := TranslatorLocalConstantInt.create(typeBoolean,
realCmpl(result.realValue, second.realValue) >= 0);
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.SLT: begin
second := parseConstShift(where, lexemes, position + 1);
case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
TranslatorType.KIND_SHORT:
result := TranslatorLocalConstantInt.create(typeBoolean,
result.shortValue < second.shortValue);
TranslatorType.KIND_INT:
result := TranslatorLocalConstantInt.create(typeBoolean,
result.intValue < second.intValue);
TranslatorType.KIND_LONG:
result := TranslatorLocalConstantInt.create(typeBoolean,
result.longValue < second.longValue);
TranslatorType.KIND_FLOAT, TranslatorType.KIND_DOUBLE, TranslatorType.KIND_REAL:
result := TranslatorLocalConstantInt.create(typeBoolean,
realCmpg(result.realValue, second.realValue) < 0);
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.SLE: begin
second := parseConstShift(where, lexemes, position + 1);
case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
TranslatorType.KIND_SHORT:
result := TranslatorLocalConstantInt.create(typeBoolean,
result.shortValue <= second.shortValue);
TranslatorType.KIND_INT:
result := TranslatorLocalConstantInt.create(typeBoolean,
result.intValue <= second.intValue);
TranslatorType.KIND_LONG:
result := TranslatorLocalConstantInt.create(typeBoolean,
result.longValue <= second.longValue);
TranslatorType.KIND_FLOAT, TranslatorType.KIND_DOUBLE, TranslatorType.KIND_REAL:
result := TranslatorLocalConstantInt.create(typeBoolean,
realCmpg(result.realValue, second.realValue) <= 0);
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.QGT: begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
end;
second := parseConstShift(where, lexemes, position + 1);
case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
TranslatorType.KIND_INT, TranslatorType.KIND_LONG:
result := TranslatorLocalConstantLong.create(typeLong,
mmxGreate(result.longValue, second.longValue));
TranslatorType.KIND_ULTRA:
result := TranslatorLocalConstantUltra.create(typeUltra,
sseiGreate(result.getUltraValue(), second.getUltraValue()));
TranslatorType.KIND_FLOAT, TranslatorType.KIND_XVECTOR:
result := TranslatorLocalConstantUltra.create(typeUltra,
ssefCmpg(result.getXVectorValue(), second.getXVectorValue()));
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.QGE: begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
end;
second := parseConstShift(where, lexemes, position + 1);
case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
TranslatorType.KIND_INT, TranslatorType.KIND_LONG:
result := TranslatorLocalConstantLong.create(typeLong, (-1) xor
mmxGreate(second.longValue, result.longValue));
TranslatorType.KIND_ULTRA:
result := TranslatorLocalConstantUltra.create(typeUltra, ultraBuild(-1, -1) xor
sseiGreate(second.getUltraValue(), result.getUltraValue()));
TranslatorType.KIND_FLOAT, TranslatorType.KIND_XVECTOR:
result := TranslatorLocalConstantUltra.create(typeUltra,
ssefCmpge(result.getXVectorValue(), second.getXVectorValue()));
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.QLT: begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
end;
second := parseConstShift(where, lexemes, position + 1);
case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
TranslatorType.KIND_INT, TranslatorType.KIND_LONG:
result := TranslatorLocalConstantLong.create(typeLong,
mmxGreate(second.longValue, result.longValue));
TranslatorType.KIND_ULTRA:
result := TranslatorLocalConstantUltra.create(typeUltra,
sseiGreate(second.getUltraValue(), result.getUltraValue()));
TranslatorType.KIND_FLOAT, TranslatorType.KIND_XVECTOR:
result := TranslatorLocalConstantUltra.create(typeUltra,
ssefCmpl(result.getXVectorValue(), second.getXVectorValue()));
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.QLE: begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
end;
second := parseConstShift(where, lexemes, position + 1);
case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
TranslatorType.KIND_INT, TranslatorType.KIND_LONG:
result := TranslatorLocalConstantLong.create(typeLong, (-1) xor
mmxGreate(result.longValue, second.longValue));
TranslatorType.KIND_ULTRA:
result := TranslatorLocalConstantUltra.create(typeUltra, ultraBuild(-1, -1) xor
sseiGreate(result.getUltraValue(), second.getUltraValue()));
TranslatorType.KIND_FLOAT, TranslatorType.KIND_XVECTOR:
result := TranslatorLocalConstantUltra.create(typeUltra,
ssefCmple(result.getXVectorValue(), second.getXVectorValue()));
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.OGT: begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
end;
second := parseConstShift(where, lexemes, position + 1);
case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
TranslatorType.KIND_INT, TranslatorType.KIND_LONG, TranslatorType.KIND_ULTRA:
result := TranslatorLocalConstantUltra.create(typeUltra,
ssesGreate(result.getUltraValue(), second.getUltraValue()));
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.OGE: begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
end;
second := parseConstShift(where, lexemes, position + 1);
case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
TranslatorType.KIND_INT, TranslatorType.KIND_LONG, TranslatorType.KIND_ULTRA:
result := TranslatorLocalConstantUltra.create(typeUltra, ultraBuild(-1, -1) xor
ssesGreate(second.getUltraValue(), result.getUltraValue()));
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.OLT: begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
end;
second := parseConstShift(where, lexemes, position + 1);
case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
TranslatorType.KIND_INT, TranslatorType.KIND_LONG, TranslatorType.KIND_ULTRA:
result := TranslatorLocalConstantUltra.create(typeUltra,
ssesGreate(second.getUltraValue(), result.getUltraValue()));
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.OLE: begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
end;
second := parseConstShift(where, lexemes, position + 1);
case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
TranslatorType.KIND_INT, TranslatorType.KIND_LONG, TranslatorType.KIND_ULTRA:
result := TranslatorLocalConstantUltra.create(typeUltra, ultraBuild(-1, -1) xor
ssesGreate(result.getUltraValue(), second.getUltraValue()));
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
else
break;
end;
until false;
end;
function TranslatorNamespacesBuilder.parseConstEqual(where: Namespace; lexemes: Lexer;
position: int): GlobalConstant;
var
second: GlobalConstant;
begin
result := parseConstRel(where, lexemes, position);
repeat
position := stayPosition;
case lexemes.getType(position) of
TranslatorLexer.SEQ: begin
{ a == b ≡ @@..@@((a ==|| b) >>..>>> 8) == -1L }
second := parseConstRel(where, lexemes, position + 1);
case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
TranslatorType.KIND_BOOLEAN:
result := TranslatorLocalConstantInt.create(typeBoolean,
result.booleanValue = second.booleanValue);
TranslatorType.KIND_SHORT:
result := TranslatorLocalConstantInt.create(typeBoolean,
result.shortValue = second.shortValue);
TranslatorType.KIND_INT:
result := TranslatorLocalConstantInt.create(typeBoolean,
result.intValue = second.intValue);
TranslatorType.KIND_LONG:
result := TranslatorLocalConstantInt.create(typeBoolean,
result.longValue = second.longValue);
TranslatorType.KIND_ULTRA:
result := TranslatorLocalConstantInt.create(typeBoolean,
ssesPack(ssesShr(sseiEquals(
result.getUltraValue(), second.getUltraValue()), $08)) = (-1));
TranslatorType.KIND_FLOAT, TranslatorType.KIND_DOUBLE, TranslatorType.KIND_REAL:
result := TranslatorLocalConstantInt.create(typeBoolean,
realCmpl(result.realValue, second.realValue) = 0);
TranslatorType.KIND_XVECTOR:
result := TranslatorLocalConstantInt.create(typeBoolean,
ssesPack(ssesShr(ssefCmpe(
result.getXVectorValue(), second.getXVectorValue()), $08)) = (-1));
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.SNE: begin
{ a != b ≡ @@..@@((a ==|| b) >>..>>> 8) != -1L }
second := parseConstRel(where, lexemes, position + 1);
case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
TranslatorType.KIND_BOOLEAN:
result := TranslatorLocalConstantInt.create(typeBoolean,
result.booleanValue <> second.booleanValue);
TranslatorType.KIND_SHORT:
result := TranslatorLocalConstantInt.create(typeBoolean,
result.shortValue <> second.shortValue);
TranslatorType.KIND_INT:
result := TranslatorLocalConstantInt.create(typeBoolean,
result.intValue <> second.intValue);
TranslatorType.KIND_LONG:
result := TranslatorLocalConstantInt.create(typeBoolean,
result.longValue <> second.longValue);
TranslatorType.KIND_ULTRA:
result := TranslatorLocalConstantInt.create(typeBoolean,
ssesPack(ssesShr(sseiEquals(
result.getUltraValue(), second.getUltraValue()), $08)) <> (-1));
TranslatorType.KIND_FLOAT, TranslatorType.KIND_DOUBLE, TranslatorType.KIND_REAL:
result := TranslatorLocalConstantInt.create(typeBoolean,
realCmpl(result.realValue, second.realValue) <> 0);
TranslatorType.KIND_XVECTOR:
result := TranslatorLocalConstantInt.create(typeBoolean,
ssesPack(ssesShr(ssefCmpe(
result.getXVectorValue(), second.getXVectorValue()), $08)) <> (-1));
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.QEQ: begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
end;
second := parseConstRel(where, lexemes, position + 1);
case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
TranslatorType.KIND_INT, TranslatorType.KIND_LONG:
result := TranslatorLocalConstantLong.create(typeLong,
mmxEquals(result.longValue, second.longValue));
TranslatorType.KIND_ULTRA:
result := TranslatorLocalConstantUltra.create(typeUltra,
sseiEquals(result.getUltraValue(), second.getUltraValue()));
TranslatorType.KIND_FLOAT, TranslatorType.KIND_XVECTOR:
result := TranslatorLocalConstantUltra.create(typeUltra,
ssefCmpe(result.getXVectorValue(), second.getXVectorValue()));
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.QNE: begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
end;
second := parseConstRel(where, lexemes, position + 1);
case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
TranslatorType.KIND_INT, TranslatorType.KIND_LONG:
result := TranslatorLocalConstantLong.create(typeLong, (-1) xor
mmxEquals(result.longValue, second.longValue));
TranslatorType.KIND_ULTRA:
result := TranslatorLocalConstantUltra.create(typeUltra, ultraBuild(-1, -1) xor
sseiEquals(result.getUltraValue(), second.getUltraValue()));
TranslatorType.KIND_FLOAT, TranslatorType.KIND_XVECTOR:
result := TranslatorLocalConstantUltra.create(typeUltra,
ssefCmpne(result.getXVectorValue(), second.getXVectorValue()));
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.OEQ: begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
end;
second := parseConstRel(where, lexemes, position + 1);
case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
TranslatorType.KIND_INT, TranslatorType.KIND_LONG, TranslatorType.KIND_ULTRA:
result := TranslatorLocalConstantUltra.create(typeUltra,
ssesEquals(result.getUltraValue(), second.getUltraValue()));
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
TranslatorLexer.ONE: begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
raise CompileError.create(msgOperationNotSupportedOS, lexemes, position);
end;
second := parseConstRel(where, lexemes, position + 1);
case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
TranslatorType.KIND_INT, TranslatorType.KIND_LONG, TranslatorType.KIND_ULTRA:
result := TranslatorLocalConstantUltra.create(typeUltra, ultraBuild(-1, -1) xor
ssesEquals(result.getUltraValue(), second.getUltraValue()));
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
else
break;
end;
until false;
end;
function TranslatorNamespacesBuilder.parseConstBAnd(where: Namespace; lexemes: Lexer;
position: int): GlobalConstant;
var
second: GlobalConstant;
begin
result := parseConstEqual(where, lexemes, position);
repeat
position := stayPosition;
if lexemes.getType(position) <> TranslatorLexer.SANDB then begin
break;
end;
second := parseConstEqual(where, lexemes, position + 1);
case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
TranslatorType.KIND_BOOLEAN:
{$BOOLEVAL ON}
result := TranslatorLocalConstantInt.create(typeBoolean,
result.booleanValue and second.booleanValue);
{$BOOLEVAL OFF}
TranslatorType.KIND_SHORT:
result := TranslatorLocalConstantInt.create(typeShort,
short(result.shortValue and second.shortValue));
TranslatorType.KIND_INT:
result := TranslatorLocalConstantInt.create(typeInt,
result.intValue and second.intValue);
TranslatorType.KIND_LONG:
result := TranslatorLocalConstantLong.create(typeLong,
result.longValue and second.longValue);
TranslatorType.KIND_ULTRA:
result := TranslatorLocalConstantUltra.create(typeUltra,
result.getUltraValue() and second.getUltraValue());
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
until false;
end;
function TranslatorNamespacesBuilder.parseConstBXor(where: Namespace; lexemes: Lexer;
position: int): GlobalConstant;
var
second: GlobalConstant;
begin
result := parseConstBAnd(where, lexemes, position);
repeat
position := stayPosition;
if lexemes.getType(position) <> TranslatorLexer.SXORB then begin
break;
end;
second := parseConstBAnd(where, lexemes, position + 1);
case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
TranslatorType.KIND_BOOLEAN:
{$BOOLEVAL ON}
result := TranslatorLocalConstantInt.create(typeBoolean,
result.booleanValue xor second.booleanValue);
{$BOOLEVAL OFF}
TranslatorType.KIND_SHORT:
result := TranslatorLocalConstantInt.create(typeShort,
short(result.shortValue xor second.shortValue));
TranslatorType.KIND_INT:
result := TranslatorLocalConstantInt.create(typeInt,
result.intValue xor second.intValue);
TranslatorType.KIND_LONG:
result := TranslatorLocalConstantLong.create(typeLong,
result.longValue xor second.longValue);
TranslatorType.KIND_ULTRA:
result := TranslatorLocalConstantUltra.create(typeUltra,
result.getUltraValue() xor second.getUltraValue());
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
until false;
end;
function TranslatorNamespacesBuilder.parseConstBOr(where: Namespace; lexemes: Lexer;
position: int): GlobalConstant;
var
second: GlobalConstant;
begin
result := parseConstBXor(where, lexemes, position);
repeat
position := stayPosition;
if lexemes.getType(position) <> TranslatorLexer.SORB then begin
break;
end;
second := parseConstBXor(where, lexemes, position + 1);
case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
TranslatorType.KIND_BOOLEAN:
{$BOOLEVAL ON}
result := TranslatorLocalConstantInt.create(typeBoolean,
result.booleanValue or second.booleanValue);
{$BOOLEVAL OFF}
TranslatorType.KIND_SHORT:
result := TranslatorLocalConstantInt.create(typeShort,
short(result.shortValue or second.shortValue));
TranslatorType.KIND_INT:
result := TranslatorLocalConstantInt.create(typeInt,
result.intValue or second.intValue);
TranslatorType.KIND_LONG:
result := TranslatorLocalConstantLong.create(typeLong,
result.longValue or second.longValue);
TranslatorType.KIND_ULTRA:
result := TranslatorLocalConstantUltra.create(typeUltra,
result.getUltraValue() or second.getUltraValue());
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
until false;
end;
function TranslatorNamespacesBuilder.parseConstLAnd(where: Namespace; lexemes: Lexer;
position: int): GlobalConstant;
var
second: GlobalConstant;
begin
result := parseConstBOr(where, lexemes, position);
repeat
position := stayPosition;
if lexemes.getType(position) <> TranslatorLexer.SANDL then begin
break;
end;
second := parseConstBOr(where, lexemes, position + 1);
case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
TranslatorType.KIND_BOOLEAN:
{$BOOLEVAL ON}
result := TranslatorLocalConstantInt.create(typeBoolean,
result.booleanValue and second.booleanValue);
{$BOOLEVAL OFF}
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
until false;
end;
function TranslatorNamespacesBuilder.parseConstLOr(where: Namespace; lexemes: Lexer;
position: int): GlobalConstant;
var
second: GlobalConstant;
begin
result := parseConstLAnd(where, lexemes, position);
repeat
position := stayPosition;
if lexemes.getType(position) <> TranslatorLexer.SORL then begin
break;
end;
second := parseConstLAnd(where, lexemes, position + 1);
case getCommonTypeKind(result.dataType.kind, second.dataType.kind) of
TranslatorType.KIND_BOOLEAN:
{$BOOLEVAL ON}
result := TranslatorLocalConstantInt.create(typeBoolean,
result.booleanValue or second.booleanValue);
{$BOOLEVAL OFF}
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
until false;
end;
function TranslatorNamespacesBuilder.parseConstCond(where: Namespace; lexemes: Lexer;
position: int): GlobalConstant;
var
vtrue: GlobalConstant;
vfalse: GlobalConstant;
begin
result := parseConstLOr(where, lexemes, position);
position := stayPosition;
if lexemes.getType(position) <> TranslatorLexer.QUESTION_MARK then begin
exit;
end;
if result.dataType.kind <> TranslatorType.KIND_BOOLEAN then begin
raise CompileError.create(msgTypeMustBeBoolean, lexemes, position);
end;
vtrue := parseConstCond(where, lexemes, position + 1);
position := stayPosition;
if lexemes.getType(position) <> TranslatorLexer.COLON then begin
raise CompileError.create(msgExpectedColon, lexemes, position);
end;
vfalse := parseConstCond(where, lexemes, position + 1);
case getCommonTypeKind(vtrue.dataType.kind, vfalse.dataType.kind) of
TranslatorType.KIND_BOOLEAN:
if result.booleanValue = true then begin
result := vtrue;
end else begin
result := vfalse;
end;
TranslatorType.KIND_SHORT:
if result.booleanValue = true then begin
result := TranslatorLocalConstantInt.create(typeShort, vtrue.shortValue);
end else begin
result := TranslatorLocalConstantInt.create(typeShort, vfalse.shortValue);
end;
TranslatorType.KIND_INT:
if result.booleanValue = true then begin
result := TranslatorLocalConstantInt.create(typeInt, vtrue.intValue);
end else begin
result := TranslatorLocalConstantInt.create(typeInt, vfalse.intValue);
end;
TranslatorType.KIND_LONG:
if result.booleanValue = true then begin
result := TranslatorLocalConstantLong.create(typeLong, vtrue.longValue);
end else begin
result := TranslatorLocalConstantLong.create(typeLong, vfalse.longValue);
end;
TranslatorType.KIND_ULTRA:
if result.booleanValue = true then begin
result := TranslatorLocalConstantUltra.create(typeUltra, vtrue.getUltraValue());
end else begin
result := TranslatorLocalConstantUltra.create(typeUltra, vfalse.getUltraValue());
end;
TranslatorType.KIND_FLOAT:
if result.booleanValue = true then begin
result := TranslatorLocalConstantReal.create(typeFloat, vtrue.realValue);
end else begin
result := TranslatorLocalConstantReal.create(typeFloat, vfalse.realValue);
end;
TranslatorType.KIND_DOUBLE:
if result.booleanValue = true then begin
result := TranslatorLocalConstantReal.create(typeDouble, vtrue.realValue);
end else begin
result := TranslatorLocalConstantReal.create(typeDouble, vfalse.realValue);
end;
TranslatorType.KIND_REAL:
if result.booleanValue = true then begin
result := TranslatorLocalConstantReal.create(typeReal, vtrue.realValue);
end else begin
result := TranslatorLocalConstantReal.create(typeReal, vfalse.realValue);
end;
TranslatorType.KIND_XVECTOR:
if result.booleanValue = true then begin
result := TranslatorLocalConstantXVector.create(typeXVector, vtrue.getXVectorValue());
end else begin
result := TranslatorLocalConstantXVector.create(typeXVector, vfalse.getXVectorValue());
end;
else
raise CompileError.create(msgCannotApplyOperation, lexemes, position);
end;
end;
function TranslatorNamespacesBuilder.possibleAssign(dstTypeKind: int;
constant: GlobalConstant): boolean;
var
srcTypeKindIsLong: boolean;
srcTypeKind: int;
srcType: TypeDescriptor;
begin
srcType := constant.dataType;
srcTypeKind := srcType.kind;
srcTypeKindIsLong :=
(srcTypeKind = TranslatorType.KIND_CHAR) or
(srcTypeKind = TranslatorType.KIND_BYTE) or
(srcTypeKind = TranslatorType.KIND_SHORT) or
(srcTypeKind = TranslatorType.KIND_INT) or
(srcTypeKind = TranslatorType.KIND_LONG);
case dstTypeKind of
TranslatorType.KIND_BOOLEAN:
result := srcType.possibleAssignTo(typeBoolean);
TranslatorType.KIND_CHAR:
result := srcTypeKindIsLong and typeChar.possibleAssignLong(constant.longValue);
TranslatorType.KIND_BYTE:
result := srcTypeKindIsLong and typeByte.possibleAssignLong(constant.longValue);
TranslatorType.KIND_SHORT:
result := srcTypeKindIsLong and typeShort.possibleAssignLong(constant.longValue);
TranslatorType.KIND_INT:
result := srcTypeKindIsLong and typeInt.possibleAssignLong(constant.longValue);
TranslatorType.KIND_LONG:
result := srcTypeKindIsLong and typeLong.possibleAssignLong(constant.longValue);
TranslatorType.KIND_ULTRA:
result := srcTypeKindIsLong and typeUltra.possibleAssignLong(constant.longValue) or
srcType.possibleAssignTo(typeUltra);
TranslatorType.KIND_FLOAT:
result := srcTypeKindIsLong and typeFloat.possibleAssignLong(constant.longValue) or
srcType.possibleAssignTo(typeFloat);
TranslatorType.KIND_DOUBLE:
result := srcTypeKindIsLong and typeDouble.possibleAssignLong(constant.longValue) or
srcType.possibleAssignTo(typeDouble);
TranslatorType.KIND_REAL:
result := srcTypeKindIsLong and typeReal.possibleAssignLong(constant.longValue) or
srcType.possibleAssignTo(typeReal);
TranslatorType.KIND_XVECTOR:
result := srcTypeKindIsLong and typeXVector.possibleAssignLong(constant.longValue) or
srcType.possibleAssignTo(typeXVector);
else
result := false;
end;
end;
function TranslatorNamespacesBuilder.skipCurlyBrackets(lexemes: Lexer; position: int): int;
var
count: int;
begin
count := 0;
repeat
case lexemes.getType(position) of
TranslatorLexer.OPENED_CURLY_BRACKET: begin
inc(count);
end;
TranslatorLexer.CLOSED_CURLY_BRACKET: begin
dec(count);
if count <= 0 then begin
break;
end;
end;
TranslatorLexer.NULL: begin
dec(position);
break;
end;
end;
inc(position);
until false;
result := position + 1;
end;
function TranslatorNamespacesBuilder.skipParenthesis(lexemes: Lexer; position: int): int;
var
count: int;
begin
count := 0;
repeat
case lexemes.getType(position) of
TranslatorLexer.OPENED_PARENTHESIS: begin
inc(count);
end;
TranslatorLexer.CLOSED_PARENTHESIS: begin
dec(count);
if count <= 0 then begin
break;
end;
end;
TranslatorLexer.NULL: begin
dec(position);
break;
end;
end;
inc(position);
until false;
result := position + 1;
end;
function TranslatorNamespacesBuilder.getCommonTypeKind(kind1, kind2: int): int;
begin
case operandSize of
TranslatorType.SIZE_16_BIT: begin
{
Общие типы данных для двух операндов при 16-битной разрядности:
────────╥────────┬────────┬────────┬────────┬────────┬────────┐
↓1 2→ ║ char │ byte │ short │ float │ double │ real │
════════╬════════╪════════╪════════╪════════╪════════╪════════╡
char ║ short │ short │ short │ real │ real │ real │
────────╫────────┼────────┼────────┼────────┼────────┼────────┤
byte ║ short │ short │ short │ real │ real │ real │
────────╫────────┼────────┼────────┼────────┼────────┼────────┤
short ║ short │ short │ short │ real │ real │ real │
────────╫────────┼────────┼────────┼────────┼────────┼────────┤
float ║ real │ real │ real │ float │ double │ real │
────────╫────────┼────────┼────────┼────────┼────────┼────────┤
double ║ real │ real │ real │ double │ double │ real │
────────╫────────┼────────┼────────┼────────┼────────┼────────┤
real ║ real │ real │ real │ real │ real │ real │
────────╨────────┴────────┴────────┴────────┴────────┴────────┘
}
case ((kind1 and $ffff) shl 16) + (kind2 and $ffff) of
(TranslatorType.KIND_BOOLEAN shl 16) + TranslatorType.KIND_BOOLEAN:
result := TranslatorType.KIND_BOOLEAN;
(TranslatorType.KIND_CHAR shl 16) + TranslatorType.KIND_CHAR,
(TranslatorType.KIND_CHAR shl 16) + TranslatorType.KIND_BYTE,
(TranslatorType.KIND_CHAR shl 16) + TranslatorType.KIND_SHORT,
(TranslatorType.KIND_BYTE shl 16) + TranslatorType.KIND_CHAR,
(TranslatorType.KIND_BYTE shl 16) + TranslatorType.KIND_BYTE,
(TranslatorType.KIND_BYTE shl 16) + TranslatorType.KIND_SHORT,
(TranslatorType.KIND_SHORT shl 16) + TranslatorType.KIND_CHAR,
(TranslatorType.KIND_SHORT shl 16) + TranslatorType.KIND_BYTE,
(TranslatorType.KIND_SHORT shl 16) + TranslatorType.KIND_SHORT:
result := TranslatorType.KIND_SHORT;
(TranslatorType.KIND_FLOAT shl 16) + TranslatorType.KIND_FLOAT:
result := TranslatorType.KIND_FLOAT;
(TranslatorType.KIND_FLOAT shl 16) + TranslatorType.KIND_DOUBLE,
(TranslatorType.KIND_DOUBLE shl 16) + TranslatorType.KIND_FLOAT,
(TranslatorType.KIND_DOUBLE shl 16) + TranslatorType.KIND_DOUBLE:
result := TranslatorType.KIND_DOUBLE;
(TranslatorType.KIND_CHAR shl 16) + TranslatorType.KIND_FLOAT,
(TranslatorType.KIND_CHAR shl 16) + TranslatorType.KIND_DOUBLE,
(TranslatorType.KIND_CHAR shl 16) + TranslatorType.KIND_REAL,
(TranslatorType.KIND_BYTE shl 16) + TranslatorType.KIND_FLOAT,
(TranslatorType.KIND_BYTE shl 16) + TranslatorType.KIND_DOUBLE,
(TranslatorType.KIND_BYTE shl 16) + TranslatorType.KIND_REAL,
(TranslatorType.KIND_SHORT shl 16) + TranslatorType.KIND_FLOAT,
(TranslatorType.KIND_SHORT shl 16) + TranslatorType.KIND_DOUBLE,
(TranslatorType.KIND_SHORT shl 16) + TranslatorType.KIND_REAL,
(TranslatorType.KIND_FLOAT shl 16) + TranslatorType.KIND_CHAR,
(TranslatorType.KIND_FLOAT shl 16) + TranslatorType.KIND_BYTE,
(TranslatorType.KIND_FLOAT shl 16) + TranslatorType.KIND_SHORT,
(TranslatorType.KIND_FLOAT shl 16) + TranslatorType.KIND_REAL,
(TranslatorType.KIND_DOUBLE shl 16) + TranslatorType.KIND_CHAR,
(TranslatorType.KIND_DOUBLE shl 16) + TranslatorType.KIND_BYTE,
(TranslatorType.KIND_DOUBLE shl 16) + TranslatorType.KIND_SHORT,
(TranslatorType.KIND_DOUBLE shl 16) + TranslatorType.KIND_REAL,
(TranslatorType.KIND_REAL shl 16) + TranslatorType.KIND_CHAR,
(TranslatorType.KIND_REAL shl 16) + TranslatorType.KIND_BYTE,
(TranslatorType.KIND_REAL shl 16) + TranslatorType.KIND_SHORT,
(TranslatorType.KIND_REAL shl 16) + TranslatorType.KIND_FLOAT,
(TranslatorType.KIND_REAL shl 16) + TranslatorType.KIND_DOUBLE,
(TranslatorType.KIND_REAL shl 16) + TranslatorType.KIND_REAL:
result := TranslatorType.KIND_REAL;
else
result := -1;
end;
end;
TranslatorType.SIZE_32_BIT: begin
{
Общие типы данных для двух операндов при 32-битной разрядности:
────────╥────────┬────────┬────────┬────────┬────────┬────────┬────────┐
↓1 2→ ║ char │ byte │ short │ int │ float │ double │ real │
════════╬════════╪════════╪════════╪════════╪════════╪════════╪════════╡
char ║ int │ int │ int │ int │ real │ real │ real │
────────╫────────┼────────┼────────┼────────┼────────┼────────┼────────┤
byte ║ int │ int │ int │ int │ real │ real │ real │
────────╫────────┼────────┼────────┼────────┼────────┼────────┼────────┤
short ║ int │ int │ int │ int │ real │ real │ real │
────────╫────────┼────────┼────────┼────────┼────────┼────────┼────────┤
int ║ int │ int │ int │ int │ real │ real │ real │
────────╫────────┼────────┼────────┼────────┼────────┼────────┼────────┤
float ║ real │ real │ real │ real │ float │ double │ real │
────────╫────────┼────────┼────────┼────────┼────────┼────────┼────────┤
double ║ real │ real │ real │ real │ double │ double │ real │
────────╫────────┼────────┼────────┼────────┼────────┼────────┼────────┤
real ║ real │ real │ real │ real │ real │ real │ real │
────────╨────────┴────────┴────────┴────────┴────────┴────────┴────────┘
}
case ((kind1 and $ffff) shl 16) + (kind2 and $ffff) of
(TranslatorType.KIND_BOOLEAN shl 16) + TranslatorType.KIND_BOOLEAN:
result := TranslatorType.KIND_BOOLEAN;
(TranslatorType.KIND_CHAR shl 16) + TranslatorType.KIND_CHAR,
(TranslatorType.KIND_CHAR shl 16) + TranslatorType.KIND_BYTE,
(TranslatorType.KIND_CHAR shl 16) + TranslatorType.KIND_SHORT,
(TranslatorType.KIND_CHAR shl 16) + TranslatorType.KIND_INT,
(TranslatorType.KIND_BYTE shl 16) + TranslatorType.KIND_CHAR,
(TranslatorType.KIND_BYTE shl 16) + TranslatorType.KIND_BYTE,
(TranslatorType.KIND_BYTE shl 16) + TranslatorType.KIND_SHORT,
(TranslatorType.KIND_BYTE shl 16) + TranslatorType.KIND_INT,
(TranslatorType.KIND_SHORT shl 16) + TranslatorType.KIND_CHAR,
(TranslatorType.KIND_SHORT shl 16) + TranslatorType.KIND_BYTE,
(TranslatorType.KIND_SHORT shl 16) + TranslatorType.KIND_SHORT,
(TranslatorType.KIND_SHORT shl 16) + TranslatorType.KIND_INT,
(TranslatorType.KIND_INT shl 16) + TranslatorType.KIND_CHAR,
(TranslatorType.KIND_INT shl 16) + TranslatorType.KIND_BYTE,
(TranslatorType.KIND_INT shl 16) + TranslatorType.KIND_SHORT,
(TranslatorType.KIND_INT shl 16) + TranslatorType.KIND_INT:
result := TranslatorType.KIND_INT;
(TranslatorType.KIND_FLOAT shl 16) + TranslatorType.KIND_FLOAT:
result := TranslatorType.KIND_FLOAT;
(TranslatorType.KIND_FLOAT shl 16) + TranslatorType.KIND_DOUBLE,
(TranslatorType.KIND_DOUBLE shl 16) + TranslatorType.KIND_FLOAT,
(TranslatorType.KIND_DOUBLE shl 16) + TranslatorType.KIND_DOUBLE:
result := TranslatorType.KIND_DOUBLE;
(TranslatorType.KIND_CHAR shl 16) + TranslatorType.KIND_FLOAT,
(TranslatorType.KIND_CHAR shl 16) + TranslatorType.KIND_DOUBLE,
(TranslatorType.KIND_CHAR shl 16) + TranslatorType.KIND_REAL,
(TranslatorType.KIND_BYTE shl 16) + TranslatorType.KIND_FLOAT,
(TranslatorType.KIND_BYTE shl 16) + TranslatorType.KIND_DOUBLE,
(TranslatorType.KIND_BYTE shl 16) + TranslatorType.KIND_REAL,
(TranslatorType.KIND_SHORT shl 16) + TranslatorType.KIND_FLOAT,
(TranslatorType.KIND_SHORT shl 16) + TranslatorType.KIND_DOUBLE,
(TranslatorType.KIND_SHORT shl 16) + TranslatorType.KIND_REAL,
(TranslatorType.KIND_INT shl 16) + TranslatorType.KIND_FLOAT,
(TranslatorType.KIND_INT shl 16) + TranslatorType.KIND_DOUBLE,
(TranslatorType.KIND_INT shl 16) + TranslatorType.KIND_REAL,
(TranslatorType.KIND_FLOAT shl 16) + TranslatorType.KIND_CHAR,
(TranslatorType.KIND_FLOAT shl 16) + TranslatorType.KIND_BYTE,
(TranslatorType.KIND_FLOAT shl 16) + TranslatorType.KIND_SHORT,
(TranslatorType.KIND_FLOAT shl 16) + TranslatorType.KIND_INT,
(TranslatorType.KIND_FLOAT shl 16) + TranslatorType.KIND_REAL,
(TranslatorType.KIND_DOUBLE shl 16) + TranslatorType.KIND_CHAR,
(TranslatorType.KIND_DOUBLE shl 16) + TranslatorType.KIND_BYTE,
(TranslatorType.KIND_DOUBLE shl 16) + TranslatorType.KIND_SHORT,
(TranslatorType.KIND_DOUBLE shl 16) + TranslatorType.KIND_INT,
(TranslatorType.KIND_DOUBLE shl 16) + TranslatorType.KIND_REAL,
(TranslatorType.KIND_REAL shl 16) + TranslatorType.KIND_CHAR,
(TranslatorType.KIND_REAL shl 16) + TranslatorType.KIND_BYTE,
(TranslatorType.KIND_REAL shl 16) + TranslatorType.KIND_SHORT,
(TranslatorType.KIND_REAL shl 16) + TranslatorType.KIND_INT,
(TranslatorType.KIND_REAL shl 16) + TranslatorType.KIND_FLOAT,
(TranslatorType.KIND_REAL shl 16) + TranslatorType.KIND_DOUBLE,
(TranslatorType.KIND_REAL shl 16) + TranslatorType.KIND_REAL:
result := TranslatorType.KIND_REAL;
else
result := -1;
end;
end;
TranslatorType.SIZE_64_BIT: begin
{
Общие типы данных для двух операндов при 64-битной разрядности:
────────╥────────┬────────┬────────┬────────┬────────┬────────┬────────┬────────┬────────┬────────┐
↓1 2→ ║ char │ byte │ short │ int │ long │ ultra │ float │ double │ real │ xvector│
════════╬════════╪════════╪════════╪════════╪════════╪════════╪════════╪════════╪════════╪════════╡
char ║ int │ int │ int │ int │ long │ ultra │ real │ real │ real │ │
────────╫────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┤
byte ║ int │ int │ int │ int │ long │ ultra │ real │ real │ real │ │
────────╫────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┤
short ║ int │ int │ int │ int │ long │ ultra │ real │ real │ real │ │
────────╫────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┤
int ║ int │ int │ int │ int │ long │ ultra │ real │ real │ real │ │
────────╫────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┤
long ║ long │ long │ long │ long │ long │ ultra │ real │ real │ real │ │
────────╫────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┤
ultra ║ ultra │ ultra │ ultra │ ultra │ ultra │ ultra │ │ │ │ │
────────╫────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┤
float ║ real │ real │ real │ real │ real │ │ float │ double │ real │ xvector│
────────╫────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┤
double ║ real │ real │ real │ real │ real │ │ double │ double │ real │ │
────────╫────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┤
real ║ real │ real │ real │ real │ real │ │ real │ real │ real │ │
────────╫────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┼────────┤
xvector║ │ │ │ │ │ │ xvector│ │ │ xvector│
────────╨────────┴────────┴────────┴────────┴────────┴────────┴────────┴────────┴────────┴────────┘
Пустые ячейки означают несовместимость типов.
В случае обнаружения несовместимости типов (например, в выражении ((float) x) **** ((ultra) y) )
будет генерироваться ошибка компиляции.
}
case ((kind1 and $ffff) shl 16) + (kind2 and $ffff) of
(TranslatorType.KIND_BOOLEAN shl 16) + TranslatorType.KIND_BOOLEAN:
result := TranslatorType.KIND_BOOLEAN;
(TranslatorType.KIND_CHAR shl 16) + TranslatorType.KIND_CHAR,
(TranslatorType.KIND_CHAR shl 16) + TranslatorType.KIND_BYTE,
(TranslatorType.KIND_CHAR shl 16) + TranslatorType.KIND_SHORT,
(TranslatorType.KIND_CHAR shl 16) + TranslatorType.KIND_INT,
(TranslatorType.KIND_BYTE shl 16) + TranslatorType.KIND_CHAR,
(TranslatorType.KIND_BYTE shl 16) + TranslatorType.KIND_BYTE,
(TranslatorType.KIND_BYTE shl 16) + TranslatorType.KIND_SHORT,
(TranslatorType.KIND_BYTE shl 16) + TranslatorType.KIND_INT,
(TranslatorType.KIND_SHORT shl 16) + TranslatorType.KIND_CHAR,
(TranslatorType.KIND_SHORT shl 16) + TranslatorType.KIND_BYTE,
(TranslatorType.KIND_SHORT shl 16) + TranslatorType.KIND_SHORT,
(TranslatorType.KIND_SHORT shl 16) + TranslatorType.KIND_INT,
(TranslatorType.KIND_INT shl 16) + TranslatorType.KIND_CHAR,
(TranslatorType.KIND_INT shl 16) + TranslatorType.KIND_BYTE,
(TranslatorType.KIND_INT shl 16) + TranslatorType.KIND_SHORT,
(TranslatorType.KIND_INT shl 16) + TranslatorType.KIND_INT:
result := TranslatorType.KIND_INT;
(TranslatorType.KIND_CHAR shl 16) + TranslatorType.KIND_LONG,
(TranslatorType.KIND_BYTE shl 16) + TranslatorType.KIND_LONG,
(TranslatorType.KIND_SHORT shl 16) + TranslatorType.KIND_LONG,
(TranslatorType.KIND_INT shl 16) + TranslatorType.KIND_LONG,
(TranslatorType.KIND_LONG shl 16) + TranslatorType.KIND_CHAR,
(TranslatorType.KIND_LONG shl 16) + TranslatorType.KIND_BYTE,
(TranslatorType.KIND_LONG shl 16) + TranslatorType.KIND_SHORT,
(TranslatorType.KIND_LONG shl 16) + TranslatorType.KIND_INT,
(TranslatorType.KIND_LONG shl 16) + TranslatorType.KIND_LONG:
result := TranslatorType.KIND_LONG;
(TranslatorType.KIND_CHAR shl 16) + TranslatorType.KIND_ULTRA,
(TranslatorType.KIND_BYTE shl 16) + TranslatorType.KIND_ULTRA,
(TranslatorType.KIND_SHORT shl 16) + TranslatorType.KIND_ULTRA,
(TranslatorType.KIND_INT shl 16) + TranslatorType.KIND_ULTRA,
(TranslatorType.KIND_LONG shl 16) + TranslatorType.KIND_ULTRA,
(TranslatorType.KIND_ULTRA shl 16) + TranslatorType.KIND_CHAR,
(TranslatorType.KIND_ULTRA shl 16) + TranslatorType.KIND_BYTE,
(TranslatorType.KIND_ULTRA shl 16) + TranslatorType.KIND_SHORT,
(TranslatorType.KIND_ULTRA shl 16) + TranslatorType.KIND_INT,
(TranslatorType.KIND_ULTRA shl 16) + TranslatorType.KIND_LONG,
(TranslatorType.KIND_ULTRA shl 16) + TranslatorType.KIND_ULTRA:
result := TranslatorType.KIND_ULTRA;
(TranslatorType.KIND_FLOAT shl 16) + TranslatorType.KIND_FLOAT:
result := TranslatorType.KIND_FLOAT;
(TranslatorType.KIND_FLOAT shl 16) + TranslatorType.KIND_DOUBLE,
(TranslatorType.KIND_DOUBLE shl 16) + TranslatorType.KIND_FLOAT,
(TranslatorType.KIND_DOUBLE shl 16) + TranslatorType.KIND_DOUBLE:
result := TranslatorType.KIND_DOUBLE;
(TranslatorType.KIND_CHAR shl 16) + TranslatorType.KIND_FLOAT,
(TranslatorType.KIND_CHAR shl 16) + TranslatorType.KIND_DOUBLE,
(TranslatorType.KIND_CHAR shl 16) + TranslatorType.KIND_REAL,
(TranslatorType.KIND_BYTE shl 16) + TranslatorType.KIND_FLOAT,
(TranslatorType.KIND_BYTE shl 16) + TranslatorType.KIND_DOUBLE,
(TranslatorType.KIND_BYTE shl 16) + TranslatorType.KIND_REAL,
(TranslatorType.KIND_SHORT shl 16) + TranslatorType.KIND_FLOAT,
(TranslatorType.KIND_SHORT shl 16) + TranslatorType.KIND_DOUBLE,
(TranslatorType.KIND_SHORT shl 16) + TranslatorType.KIND_REAL,
(TranslatorType.KIND_INT shl 16) + TranslatorType.KIND_FLOAT,
(TranslatorType.KIND_INT shl 16) + TranslatorType.KIND_DOUBLE,
(TranslatorType.KIND_INT shl 16) + TranslatorType.KIND_REAL,
(TranslatorType.KIND_LONG shl 16) + TranslatorType.KIND_FLOAT,
(TranslatorType.KIND_LONG shl 16) + TranslatorType.KIND_DOUBLE,
(TranslatorType.KIND_LONG shl 16) + TranslatorType.KIND_REAL,
(TranslatorType.KIND_FLOAT shl 16) + TranslatorType.KIND_CHAR,
(TranslatorType.KIND_FLOAT shl 16) + TranslatorType.KIND_BYTE,
(TranslatorType.KIND_FLOAT shl 16) + TranslatorType.KIND_SHORT,
(TranslatorType.KIND_FLOAT shl 16) + TranslatorType.KIND_INT,
(TranslatorType.KIND_FLOAT shl 16) + TranslatorType.KIND_LONG,
(TranslatorType.KIND_FLOAT shl 16) + TranslatorType.KIND_REAL,
(TranslatorType.KIND_DOUBLE shl 16) + TranslatorType.KIND_CHAR,
(TranslatorType.KIND_DOUBLE shl 16) + TranslatorType.KIND_BYTE,
(TranslatorType.KIND_DOUBLE shl 16) + TranslatorType.KIND_SHORT,
(TranslatorType.KIND_DOUBLE shl 16) + TranslatorType.KIND_INT,
(TranslatorType.KIND_DOUBLE shl 16) + TranslatorType.KIND_LONG,
(TranslatorType.KIND_DOUBLE shl 16) + TranslatorType.KIND_REAL,
(TranslatorType.KIND_REAL shl 16) + TranslatorType.KIND_CHAR,
(TranslatorType.KIND_REAL shl 16) + TranslatorType.KIND_BYTE,
(TranslatorType.KIND_REAL shl 16) + TranslatorType.KIND_SHORT,
(TranslatorType.KIND_REAL shl 16) + TranslatorType.KIND_INT,
(TranslatorType.KIND_REAL shl 16) + TranslatorType.KIND_LONG,
(TranslatorType.KIND_REAL shl 16) + TranslatorType.KIND_FLOAT,
(TranslatorType.KIND_REAL shl 16) + TranslatorType.KIND_DOUBLE,
(TranslatorType.KIND_REAL shl 16) + TranslatorType.KIND_REAL:
result := TranslatorType.KIND_REAL;
(TranslatorType.KIND_FLOAT shl 16) + TranslatorType.KIND_XVECTOR,
(TranslatorType.KIND_XVECTOR shl 16) + TranslatorType.KIND_FLOAT,
(TranslatorType.KIND_XVECTOR shl 16) + TranslatorType.KIND_XVECTOR:
result := TranslatorType.KIND_XVECTOR;
else
result := -1;
end;
end;
else
result := -1;
end;
end;
function TranslatorNamespacesBuilder.castConstTo(newTypeKind: int;
constant: GlobalConstant): GlobalConstant;
begin
case newTypeKind of
TranslatorType.KIND_BOOLEAN:
result := TranslatorLocalConstantInt.create(typeBoolean, constant.booleanValue);
TranslatorType.KIND_CHAR:
result := TranslatorLocalConstantInt.create(typeChar, constant.charValue);
TranslatorType.KIND_BYTE:
result := TranslatorLocalConstantInt.create(typeByte, constant.byteValue);
TranslatorType.KIND_SHORT:
result := TranslatorLocalConstantInt.create(typeShort, constant.shortValue);
TranslatorType.KIND_INT:
result := TranslatorLocalConstantInt.create(typeInt, constant.intValue);
TranslatorType.KIND_LONG:
result := TranslatorLocalConstantLong.create(typeLong, constant.longValue);
TranslatorType.KIND_ULTRA:
result := TranslatorLocalConstantUltra.create(typeUltra, constant.getUltraValue());
TranslatorType.KIND_FLOAT:
result := TranslatorLocalConstantReal.create(typeFloat, constant.realValue);
TranslatorType.KIND_DOUBLE:
result := TranslatorLocalConstantReal.create(typeDouble, constant.realValue);
TranslatorType.KIND_REAL:
result := TranslatorLocalConstantReal.create(typeReal, constant.realValue);
TranslatorType.KIND_XVECTOR:
result := TranslatorLocalConstantXVector.create(typeXVector, constant.getXVectorValue());
else
result := nil;
end;
end;
function TranslatorNamespacesBuilder.tryParseType(where: Namespace; position: int): TypeDescriptor;
var
lexemes: Lexer;
argType: TypeDescriptor;
place: Namespace;
entry: NamespaceEntry;
ident: UnicodeString;
begin
lexemes := where.lexemes;
case lexemes.getType(position) of
TranslatorLexer.KW_VOID: begin
result := typeVoid;
end;
TranslatorLexer.KW_BOOLEAN: begin
result := typeBoolean;
end;
TranslatorLexer.KW_CHAR: begin
result := typeChar;
end;
TranslatorLexer.KW_BYTE: begin
result := typeByte;
end;
TranslatorLexer.KW_SHORT: begin
result := typeShort;
end;
TranslatorLexer.KW_INT: begin
if operandSize < TranslatorType.SIZE_32_BIT then begin
result := nil;
exit;
end;
result := typeInt;
end;
TranslatorLexer.KW_LONG: begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
result := nil;
exit;
end;
result := typeLong;
end;
TranslatorLexer.KW_ULTRA: begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
result := nil;
exit;
end;
result := typeUltra;
end;
TranslatorLexer.KW_FLOAT: begin
result := typeFloat;
end;
TranslatorLexer.KW_DOUBLE: begin
result := typeDouble;
end;
TranslatorLexer.KW_REAL: begin
result := typeReal;
end;
TranslatorLexer.KW_XVECTOR: begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
result := nil;
exit;
end;
result := typeXVector;
end;
TranslatorLexer.KW_YVECTOR, TranslatorLexer.KW_ULTRA32,
TranslatorLexer.KW_ZVECTOR, TranslatorLexer.KW_ULTRA64,
TranslatorLexer.KW_FVECTOR: begin
result := nil;
exit;
end;
TranslatorLexer.IDENTIFIER: begin
ident := lexemes.getValueUString(position);
entry := where.findEntry(ident, true);
if entry = nil then begin
place := findNamespace(ident);
if place = nil then begin
result := nil;
exit;
end;
inc(position);
if lexemes.getType(position) <> TranslatorLexer.PERIOD then begin
result := nil;
exit;
end;
inc(position);
if lexemes.getType(position) <> TranslatorLexer.IDENTIFIER then begin
result := nil;
exit;
end;
ident := lexemes.getValueUString(position);
entry := place.findEntry(ident, false);
if not (entry is TypeDescriptor) or not where.isVisible(entry) then begin
result := nil;
exit;
end;
result := entry as TypeDescriptor;
end else
if entry is TypeDescriptor then begin
result := entry as TypeDescriptor;
end else begin
result := nil;
exit;
end;
end;
else
result := nil;
exit;
end;
inc(position);
repeat
case lexemes.getType(position) of
TranslatorLexer.OPENED_PARENTHESIS: begin
if not result.isMatchForReturnType() then begin
result := nil;
exit;
end;
inc(position);
result := TranslatorTypeFunction.create(operandSize, result);
if lexemes.getType(position) <> TranslatorLexer.CLOSED_PARENTHESIS then begin
repeat
argType := tryParseType(where, position);
if argType = nil then begin
result := nil;
exit;
end;
position := stayPosition;
if not argType.isMatchForVariable() then begin
result := nil;
exit;
end;
(result as TypeFunction).addArgument(argType, '');
if lexemes.getType(position) <> TranslatorLexer.COMMA then begin
break;
end;
inc(position);
until false;
if lexemes.getType(position) <> TranslatorLexer.CLOSED_PARENTHESIS then begin
result := nil;
exit;
end;
end;
inc(position);
result := getCanonicalType(result);
end;
TranslatorLexer.OPENED_SQUARE_BRACKET: begin
if not result.isMatchForVariable() then begin
result := nil;
exit;
end;
inc(position);
if lexemes.getType(position) <> TranslatorLexer.CLOSED_SQUARE_BRACKET then begin
dec(position);
break;
end;
inc(position);
result := getCanonicalType(TranslatorTypeArray.create(operandSize, result));
end;
else
break;
end;
until false;
stayPosition := position;
end;
function TranslatorNamespacesBuilder.parseConst(where: Namespace; position: int): GlobalConstant;
begin
result := parseConstCond(where, where.lexemes, position);
end;
function TranslatorNamespacesBuilder.parseType(where: Namespace; position: int): TypeDescriptor;
var
lexemes: Lexer;
argType: TypeDescriptor;
place: Namespace;
entry: NamespaceEntry;
ident: UnicodeString;
begin
lexemes := where.lexemes;
case lexemes.getType(position) of
TranslatorLexer.KW_VOID: begin
result := typeVoid;
end;
TranslatorLexer.KW_BOOLEAN: begin
result := typeBoolean;
end;
TranslatorLexer.KW_CHAR: begin
result := typeChar;
end;
TranslatorLexer.KW_BYTE: begin
result := typeByte;
end;
TranslatorLexer.KW_SHORT: begin
result := typeShort;
end;
TranslatorLexer.KW_INT: begin
if operandSize < TranslatorType.SIZE_32_BIT then begin
raise CompileError.create(msgTypeNotSupported, lexemes, position);
end;
result := typeInt;
end;
TranslatorLexer.KW_LONG: begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
raise CompileError.create(msgTypeNotSupported, lexemes, position);
end;
result := typeLong;
end;
TranslatorLexer.KW_ULTRA: begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
raise CompileError.create(msgTypeNotSupported, lexemes, position);
end;
result := typeUltra;
end;
TranslatorLexer.KW_FLOAT: begin
result := typeFloat;
end;
TranslatorLexer.KW_DOUBLE: begin
result := typeDouble;
end;
TranslatorLexer.KW_REAL: begin
result := typeReal;
end;
TranslatorLexer.KW_XVECTOR: begin
if operandSize < TranslatorType.SIZE_64_BIT then begin
raise CompileError.create(msgTypeNotSupported, lexemes, position);
end;
result := typeXVector;
end;
TranslatorLexer.KW_YVECTOR, TranslatorLexer.KW_ULTRA32,
TranslatorLexer.KW_ZVECTOR, TranslatorLexer.KW_ULTRA64,
TranslatorLexer.KW_FVECTOR: begin
raise CompileError.create(msgTypeReserved, lexemes, position);
end;
TranslatorLexer.IDENTIFIER: begin
ident := lexemes.getValueUString(position);
entry := where.findEntry(ident, true);
if entry = nil then begin
place := findNamespace(ident);
if place = nil then begin
raise CompileError.create(msgExpectedDataType, lexemes, position);
end;
inc(position);
if lexemes.getType(position) <> TranslatorLexer.PERIOD then begin
raise CompileError.create(msgExpectedPeriod, lexemes, position);
end;
inc(position);
if lexemes.getType(position) <> TranslatorLexer.IDENTIFIER then begin
raise CompileError.create(msgExpectedIdentifierOfDataType, lexemes, position);
end;
ident := lexemes.getValueUString(position);
entry := place.findEntry(ident, false);
if not (entry is TypeDescriptor) or not where.isVisible(entry) then begin
raise CompileError.create(msgExpectedIdentifierOfDataType, lexemes, position);
end;
result := entry as TypeDescriptor;
end else
if entry is TypeDescriptor then begin
result := entry as TypeDescriptor;
end else begin
raise CompileError.create(msgExpectedIdentifierOfDataType, lexemes, position);
end;
end;
else
raise CompileError.create(msgExpectedDataType, lexemes, position);
end;
inc(position);
repeat
case lexemes.getType(position) of
TranslatorLexer.OPENED_PARENTHESIS: begin
if not result.isMatchForReturnType() then begin
raise CompileError.create(msgTypeNotApplicableToFunc, lexemes, position);
end;
inc(position);
result := TranslatorTypeFunction.create(operandSize, result);
if lexemes.getType(position) <> TranslatorLexer.CLOSED_PARENTHESIS then begin
repeat
argType := parseType(where, position);
position := stayPosition;
if not argType.isMatchForVariable() then begin
raise CompileError.create(msgTypeNotApplicableToVar, lexemes, position);
end;
(result as TypeFunction).addArgument(argType, '');
if lexemes.getType(position) <> TranslatorLexer.COMMA then begin
break;
end;
inc(position);
until false;
if lexemes.getType(position) <> TranslatorLexer.CLOSED_PARENTHESIS then begin
raise CompileError.create(msgExpectedClosedParenthesis, lexemes, position);
end;
end;
inc(position);
result := getCanonicalType(result);
end;
TranslatorLexer.OPENED_SQUARE_BRACKET: begin
if not result.isMatchForVariable() then begin
raise CompileError.create(msgTypeNotApplicableToVar, lexemes, position);
end;
inc(position);
if lexemes.getType(position) <> TranslatorLexer.CLOSED_SQUARE_BRACKET then begin
raise CompileError.create(msgExpectedClosedSquareBracket, lexemes, position);
end;
inc(position);
result := getCanonicalType(TranslatorTypeArray.create(operandSize, result));
end;
else
break;
end;
until false;
stayPosition := position;
end;
function TranslatorNamespacesBuilder.getCanonicalType(theType: TypeDescriptor): TypeDescriptor;
var
i: int;
c: int;
current: TypeDescriptor;
typeAsObject: TObject;
types: TypeDescriptor_Array1d;
newtypes: TypeDescriptor_Array1d;
begin
c := self.typesCount;
types := self.types;
typeAsObject := theType as TObject;
for i := c - 1 downto 0 do begin
current := types[i];
if current.equals(typeAsObject) then begin
result := current;
exit;
end;
end;
if length(types) = c then begin
newtypes := TypeDescriptor_Array1d(Interface_Array1d_create((c shl 1) + 1));
arraycopyInterfaces(types, 0, newtypes, 0, c);
self.types := newtypes;
types := newtypes;
end;
self.typesCount := c + 1;
types[c] := theType;
result := theType;
end;
{ TranslatorLocalConstantInt }
constructor TranslatorLocalConstantInt.create(constType: TypeDescriptor;
const constValue: boolean);
begin
inherited create(nil, false, '', constType, int(constValue));
end;
constructor TranslatorLocalConstantInt.create(constType: TypeDescriptor;
const constValue: int);
begin
inherited create(nil, false, '', constType, constValue);
end;
{ TranslatorLocalConstantLong }
constructor TranslatorLocalConstantLong.create(constType: TypeDescriptor;
const constValue: int64);
begin
inherited create(nil, false, '', constType, constValue);
end;
{ TranslatorLocalConstantReal }
constructor TranslatorLocalConstantReal.create(constType: TypeDescriptor;
const constValue: real);
begin
inherited create(nil, false, '', constType, constValue);
end;
{ TranslatorLocalConstantUltra }
constructor TranslatorLocalConstantUltra.create(constType: TypeDescriptor;
const constValue: ultra);
begin
inherited create(nil, false, '', constType, constValue);
end;
{ TranslatorLocalConstantXVector }
constructor TranslatorLocalConstantXVector.create(constType: TypeDescriptor;
const constValue: xvector);
begin
inherited create(nil, false, '', constType, constValue);
end;
end.