{
Этот исходный код является частью проекта ПВТ-ОО.
Copyright © 2021 Малик Разработчик
Это свободная программа: вы можете перераспространять её и/или
изменять её на условиях Стандартной общественной лицензии GNU в том виде,
в каком она была опубликована Фондом свободного программного обеспечения;
либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.
Эта программа распространяется в надежде, что она может быть полезна,
но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЁННЫХ ЦЕЛЕЙ. Подробнее см. в Стандартной
общественной лицензии GNU.
Вы должны были получить копию Стандартной общественной лицензии GNU
вместе с этой программой. Если это не так, см.
<http://www.gnu.org/licenses/>.
}
unit ru.malik.elaborarer.avt.constant;
{$MODE DELPHI}
interface
uses
pascalx.lang,
pascalx.utils,
ru.malik.elaborarer.avt.programme,
ru.malik.elaborarer.avt.lexer,
ru.malik.elaborarer.avt.operation;
{$ASMMODE INTEL,CALLING REGISTER,TYPEINFO ON}
(*
Имена должны сопоставляться с объектами программы только с помощью функций resolveName и resolveMember! (сделано)
*)
{%region public }
type
AVTUnaryOperatorStackItem = class(_Object)
private
fldPosition: int;
fldOperatorKind: int;
fldTypeCast: AVTType;
public
constructor create(position, operatorKind: int; typeCast: AVTType = nil);
property position: int read fldPosition write fldPosition;
property operatorKind: int read fldOperatorKind write fldOperatorKind;
property typeCast: AVTType read fldTypeCast write fldTypeCast;
end;
AVTConstantExpression = class(AVTOperation)
protected
class function parseFullyQualifiedTypeName(packageRef: AVTPackage; typeRef: AVTTypeStructured; pos: int): AVTTypeStructured; static;
class function tryParseFullyQualifiedTypeName(packageRef: AVTPackage; typeRef: AVTTypeStructured; pos: int): AVTTypeStructured; static;
class function resolveMember(where: AVTTypeStructured; const simpleName: AnsiString; typeRef: AVTTypeStructured; pos: int): AVTMember; static;
public
class function itemToString(itemRef: AVTItemExt): AnsiString; static;
class function commonType(type1Ref, type2Ref: AVTType): AVTType; static;
private
fldTypeClassRef: AVTTypeStructured;
fldTypeStringRef: AVTTypeStructured;
function parsePostfix(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
function parsePrimary(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
function parsePrefix(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
function parseMultiplicative(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
function parseAdditive(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
function parseShift(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
function parseRelational(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
function parseEquality(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
function parseBitAnd(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
function parseBitXor(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
function parseBitOr(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
function parseBoolAnd(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
function parseBoolOr(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
function parseConditional(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
function tryParseType(typeRef: AVTTypeStructured; source: AVTSource; pos: int): AVTType;
protected
procedure parseFieldInitialValue(fieldRef: AVTField);
procedure parsePropertyImplementation(propertyRef: AVTProperty);
function parseConstantExpression(dst: AVTConstant; typeRef: AVTTypeStructured; pos: int): int;
function parseType(typeRef: AVTTypeStructured; pos: int): AVTType;
function resolveName(const simpleName: AnsiString; typeRef: AVTTypeStructured; pos: int): AVTItem;
public
procedure cast(dst, op0: AVTConstant; typeNewRef: AVTTypePrimitive);
function getPrimitiveType(kind: int): AVTTypePrimitive;
function getStringType(): AVTTypeStructured;
function getClassType(): AVTTypeStructured;
end;
{%endregion}
implementation
{%region AVTUnaryOperatorStackItem }
constructor AVTUnaryOperatorStackItem.create(position, operatorKind: int; typeCast: AVTType);
begin
inherited create();
self.fldPosition := position;
self.fldOperatorKind := operatorKind;
self.fldTypeCast := typeCast;
end;
{%endregion}
{%region AVTConstantExpression }
class function AVTConstantExpression.parseFullyQualifiedTypeName(packageRef: AVTPackage; typeRef: AVTTypeStructured; pos: int): AVTTypeStructured;
var
simpleName: AnsiString;
source: AVTSource;
nextPackageRef: AVTPackage;
nextTypeRef: AVTTypeStructured;
begin
source := typeRef.source;
repeat
if source.getLexemeType(pos) <> CHAR_PERIOD then begin
raise AVTCompilerException.create('"." expected', source, pos);
end;
inc(pos);
if source.getLexemeType(pos) <> LITR_NAME then begin
raise AVTCompilerException.create('Type or package name expected', source, pos);
end;
simpleName := source.getLexemeAnsiString(pos);
nextTypeRef := packageRef.getType(simpleName) as AVTTypeStructured;
if nextTypeRef <> nil then break;
nextPackageRef := packageRef.getSubpackage(simpleName);
if nextPackageRef = nil then begin
raise AVTCompilerException.create('Package not found: ' + packageRef.fullName + '.' + simpleName, source, pos);
end;
packageRef := nextPackageRef;
inc(pos);
until false;
if not nextTypeRef.isVisible(nil, typeRef) then begin
raise AVTCompilerException.create('The type ' + nextTypeRef.fullName + ' is not visible', source, pos);
end;
source.position := pos + 1;
result := nextTypeRef;
end;
class function AVTConstantExpression.tryParseFullyQualifiedTypeName(packageRef: AVTPackage; typeRef: AVTTypeStructured; pos: int): AVTTypeStructured;
var
simpleName: AnsiString;
source: AVTSource;
nextPackageRef: AVTPackage;
nextTypeRef: AVTTypeStructured;
begin
source := typeRef.source;
repeat
if source.getLexemeType(pos) <> CHAR_PERIOD then begin
result := nil;
exit;
end;
inc(pos);
if source.getLexemeType(pos) <> LITR_NAME then begin
result := nil;
exit;
end;
simpleName := source.getLexemeAnsiString(pos);
nextTypeRef := packageRef.getType(simpleName) as AVTTypeStructured;
if nextTypeRef <> nil then break;
nextPackageRef := packageRef.getSubpackage(simpleName);
if nextPackageRef = nil then begin
result := nil;
exit;
end;
packageRef := nextPackageRef;
inc(pos);
until false;
if not nextTypeRef.isVisible(nil, typeRef) then begin
result := nil;
exit;
end;
source.position := pos + 1;
result := nextTypeRef;
end;
class function AVTConstantExpression.resolveMember(where: AVTTypeStructured; const simpleName: AnsiString; typeRef: AVTTypeStructured; pos: int): AVTMember;
var
member: AVTMember;
begin
member := where.getMember(simpleName);
if (member is AVTField) or (member is AVTProperty) then begin
member := where.findField(simpleName, typeRef, pos);
end;
if (member <> nil) and not(member is AVTMethod) and not member.isVisible(where, typeRef) then begin
raise AVTCompilerException.create('The field ' + simpleName + ' is not visible', typeRef.source, pos);
end;
result := member;
end;
class function AVTConstantExpression.itemToString(itemRef: AVTItemExt): AnsiString;
begin
if itemRef = nil then begin
result := 'null';
exit;
end;
result := itemRef.fullName;
end;
class function AVTConstantExpression.commonType(type1Ref, type2Ref: AVTType): AVTType;
begin
if type1Ref <> nil then begin
result := type1Ref.getCommonType(type2Ref);
exit;
end;
if type2Ref <> nil then begin
result := type2Ref.getCommonType(type1Ref);
exit;
end;
result := nil;
end;
function AVTConstantExpression.parsePostfix(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
label
label0;
var
index: int;
operatorPos: int;
op1: AVTConstant;
typeOperand0Ref: AVTType;
typeOperand1Ref: AVTType;
begin
repeat
operatorPos := pos;
case source.getLexemeType(pos) of
CHAR_BRACKET_OPENED: begin
op1 := AVTConstant.create();
try
pos := parseConditional(op1, typeRef, source, pos + 1);
if source.getLexemeType(pos) <> CHAR_BRACKET_CLOSED then begin
raise AVTCompilerException.create('"]" expected', source, pos);
end;
inc(pos);
typeOperand0Ref := dst.valueType;
typeOperand1Ref := op1.valueType;
if not(typeOperand1Ref is AVTTypePrimitive) then begin
goto label0;
end;
case AVTTypePrimitive(typeOperand1Ref).primitiveKind of
AVT_BYTE: begin
index := op1.value.asByte;
end;
AVT_SHORT: begin
index := op1.value.asShort;
end;
AVT_INT: begin
index := op1.value.asInt;
end
else
goto label0;
end;
if typeOperand0Ref = getStringType() then begin
if dst.value.isNull then begin
raise AVTCompilerException.create('Null pointer error', source, operatorPos);
end;
if (index < 0) or (index >= length(dst.value.asString)) then begin
raise AVTCompilerException.create('Index (' + intToString(index) + ') out of bounds', source, pos - 1);
end;
dst.value.asChar := dst.value.asString[index + 1];
dst.value.asString := '';
dst.valueType := getPrimitiveType(AVT_CHAR);
continue;
end;
if typeOperand0Ref is AVTTypePrimitive then begin
case AVTTypePrimitive(typeOperand0Ref).primitiveKind of
AVT_BYTE2, AVT_BYTE4, AVT_BYTE8: begin
if (index < 0) or (index >= AVTTypePrimitive(typeOperand0Ref).compoundLength) then begin
raise AVTCompilerException.create('Index (' + intToString(index) + ') out of bounds', source, pos - 1);
end;
dst.value.asByte := dst.value.asByte8[index];
dst.valueType := getPrimitiveType(AVT_BYTE);
continue;
end;
AVT_SHORT2, AVT_SHORT4, AVT_SHORT8: begin
if (index < 0) or (index >= AVTTypePrimitive(typeOperand0Ref).compoundLength) then begin
raise AVTCompilerException.create('Index (' + intToString(index) + ') out of bounds', source, pos - 1);
end;
dst.value.asShort := dst.value.asShort8[index];
dst.valueType := getPrimitiveType(AVT_SHORT);
continue;
end;
AVT_INT2, AVT_INT4, AVT_INT8: begin
if (index < 0) or (index >= AVTTypePrimitive(typeOperand0Ref).compoundLength) then begin
raise AVTCompilerException.create('Index (' + intToString(index) + ') out of bounds', source, pos - 1);
end;
dst.value.asInt := dst.value.asInt8[index];
dst.valueType := getPrimitiveType(AVT_INT);
continue;
end;
AVT_LONG2, AVT_LONG4, AVT_LONG8: begin
if (index < 0) or (index >= AVTTypePrimitive(typeOperand0Ref).compoundLength) then begin
raise AVTCompilerException.create('Index (' + intToString(index) + ') out of bounds', source, pos - 1);
end;
dst.value.asLong := dst.value.asLong8[index];
dst.valueType := getPrimitiveType(AVT_LONG);
continue;
end;
AVT_FLOAT2, AVT_FLOAT4, AVT_FLOAT8: begin
if (index < 0) or (index >= AVTTypePrimitive(typeOperand0Ref).compoundLength) then begin
raise AVTCompilerException.create('Index (' + intToString(index) + ') out of bounds', source, pos - 1);
end;
dst.value.asFloat := dst.value.asFloat8[index];
dst.valueType := getPrimitiveType(AVT_FLOAT);
continue;
end;
AVT_DOUBLE2, AVT_DOUBLE4, AVT_DOUBLE8: begin
if (index < 0) or (index >= AVTTypePrimitive(typeOperand0Ref).compoundLength) then begin
raise AVTCompilerException.create('Index (' + intToString(index) + ') out of bounds', source, pos - 1);
end;
dst.value.asDouble := dst.value.asDouble8[index];
dst.valueType := getPrimitiveType(AVT_DOUBLE);
continue;
end;
end;
end;
label0:
finally
op1.free();
end;
raise AVTCompilerException.create('The operator [] is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
end;
CHAR_PERIOD: begin
inc(pos);
if (source.getLexemeType(pos) <> LITR_NAME) or (source.getLexemeAnsiString(pos) <> 'length') then begin
raise AVTCompilerException.create('"length" expected', source, pos);
end;
inc(pos);
if dst.valueType = getStringType() then begin
if dst.value.isNull then begin
raise AVTCompilerException.create('Null pointer error', source, operatorPos);
end;
dst.value.asInt := length(dst.value.asString);
dst.value.asString := '';
dst.valueType := getPrimitiveType(AVT_INT);
continue;
end;
raise AVTCompilerException.create('Expression of the type avt.lang.String expected', source, operatorPos);
end
else
break;
end;
until false;
result := pos;
end;
function AVTConstantExpression.parsePrimary(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
var
i: int;
lxt: int;
lim: int;
kind: int;
name: AnsiString;
found: AVTItem;
field: AVTField;
member: AVTMember;
element: AVTConstant;
typeParsedRef: AVTType;
typeElementRef: AVTType;
typePrimitiveRef: AVTTypePrimitive;
begin
dst.clear();
lxt := source.getLexemeType(pos);
case lxt of
AVT_NEW: begin
inc(pos);
lxt := source.getLexemeType(pos);
case lxt of
AVT_BYTE2, AVT_BYTE4, AVT_BYTE8: begin
kind := AVT_BYTE;
end;
AVT_SHORT2, AVT_SHORT4, AVT_SHORT8: begin
kind := AVT_SHORT;
end;
AVT_INT2, AVT_INT4, AVT_INT8: begin
kind := AVT_INT;
end;
AVT_LONG2, AVT_LONG4, AVT_LONG8: begin
kind := AVT_LONG;
end;
AVT_FLOAT2, AVT_FLOAT4, AVT_FLOAT8: begin
kind := AVT_FLOAT;
end;
AVT_DOUBLE2, AVT_DOUBLE4, AVT_DOUBLE8: begin
kind := AVT_DOUBLE;
end
else
raise AVTCompilerException.create('Vector type expected', source, pos);
end;
typePrimitiveRef := getPrimitiveType(kind);
inc(pos);
if source.getLexemeType(pos) <> CHAR_CURLY_OPENED then begin
raise AVTCompilerException.create('"{" expected', source, pos);
end;
inc(pos);
lim := (1 shl (lxt and 3)) - 1;
element := AVTConstant.create();
try
for i := 0 to lim do begin
pos := parseConditional(element, typeRef, source, pos);
typeElementRef := element.valueType;
if not typePrimitiveRef.isConvertableFrom(typeElementRef) then begin
raise AVTCompilerException.create('Can not assign value of the type ' + itemToString(typeElementRef) + ' to vector element of the type ' + itemToString(typePrimitiveRef), source, pos);
end;
cast(element, element, typePrimitiveRef);
case kind of
AVT_BYTE: dst.value.asByte8[i] := element.value.asByte;
AVT_SHORT: dst.value.asShort8[i] := element.value.asShort;
AVT_INT: dst.value.asInt8[i] := element.value.asInt;
AVT_LONG: dst.value.asLong8[i] := element.value.asLong;
AVT_FLOAT: dst.value.asFloat8[i] := element.value.asFloat;
AVT_DOUBLE: dst.value.asDouble8[i] := element.value.asDouble;
end;
if i < lim then begin
if source.getLexemeType(pos) <> CHAR_COMMA then begin
raise AVTCompilerException.create('"," expected', source, pos);
end;
end else begin
if source.getLexemeType(pos) <> CHAR_CURLY_CLOSED then begin
raise AVTCompilerException.create('"}" expected', source, pos);
end;
end;
inc(pos);
end;
finally
element.free();
end;
dst.valueType := getPrimitiveType(lxt);
end;
AVT_NULL: begin
dst.value.isNull := true;
inc(pos);
end;
CHAR_PARENTH_OPENED: begin
pos := parseConditional(dst, typeRef, source, pos + 1);
if source.getLexemeType(pos) <> CHAR_PARENTH_CLOSED then begin
raise AVTCompilerException.create('")" expected', source, pos);
end;
inc(pos);
end;
LITR_NAME, AVT_VOID..AVT_DOUBLE8: begin
if lxt <> LITR_NAME then begin
found := parseType(typeRef, pos);
pos := source.position;
end else begin
name := source.getLexemeAnsiString(pos);
found := resolveName(name, typeRef, pos);
if found = nil then begin
raise AVTCompilerException.create(name + ' can not be resolved to a field', source, pos);
end;
if (found is AVTPackage) or (found is AVTType) then begin
found := parseType(typeRef, pos);
pos := source.position;
end else begin
if found is AVTMethod then begin
raise AVTCompilerException.create('Methods is not allowed here', source, pos);
end;
if found is AVTProperty then begin
raise AVTCompilerException.create('Properties is not allowed here', source, pos);
end;
inc(pos);
end;
end;
field := nil;
if found is AVTType then begin
typeParsedRef := AVTType(found);
if source.getLexemeType(pos) <> CHAR_PERIOD then begin
raise AVTCompilerException.create('"." expected', source, pos);
end;
inc(pos);
case source.getLexemeType(pos) of
LITR_NAME: begin
if not(typeParsedRef is AVTTypeStructured) then begin
raise AVTCompilerException.create('"class" expected', source, pos);
end;
name := source.getLexemeAnsiString(pos);
member := resolveMember(AVTTypeStructured(typeParsedRef), name, typeRef, pos);
if member is AVTMethod then begin
raise AVTCompilerException.create('Methods is not allowed here', source, pos);
end;
if member is AVTProperty then begin
raise AVTCompilerException.create('Properties is not allowed here', source, pos);
end;
if not(member is AVTField) then begin
raise AVTCompilerException.create(name + ' can not be resolved or is not a field', source, pos);
end;
field := AVTField(member);
inc(pos);
end;
AVT_CLASS: begin
if typeParsedRef is AVTTypeArray then begin
AVTTypeArray(typeParsedRef).makeCompilable();
end;
dst.value.asClass := typeParsedRef;
dst.valueType := getClassType();
inc(pos);
end
else
if not(typeParsedRef is AVTTypeStructured) then begin
raise AVTCompilerException.create('"class" expected', source, pos);
end;
raise AVTCompilerException.create('Field name or "class" expected', source, pos);
end;
end else
if found is AVTField then begin
field := AVTField(found);
end else begin
raise AVTCompilerException.create('Field name expected', source, pos);
end;
if field <> nil then begin
if ((field.flags and (FLAG_STATIC or FLAG_FINAL)) <> (FLAG_STATIC or FLAG_FINAL)) or (field.implementationPosition < 0) then begin
raise AVTCompilerException.create('The field ' + field.simpleName + ' is not a constant value', source, pos - 1);
end;
if field.valueConstCreating then begin
raise AVTCompilerException.create('The value of the field ' + field.simpleName + ' is defined through itself', source, pos - 1);
end;
if not field.valueConstCreated then begin
parseFieldInitialValue(field);
end;
dst.assign(field.valueConst);
end;
end;
LITR_STRING: begin
dst.value.asString := source.getLexemeUnicodeString(pos);
dst.valueType := getStringType();
inc(pos);
end;
LITR_BOOLEAN: begin
dst.value.asBoolean := source.getLexemeBoolean(pos);
dst.valueType := getPrimitiveType(AVT_BOOLEAN);
inc(pos);
end;
LITR_CHAR: begin
dst.value.asChar := source.getLexemeChar(pos);
dst.valueType := getPrimitiveType(AVT_CHAR);
inc(pos);
end;
LITR_REAL: begin
dst.value.asReal := source.getLexemeReal(pos);
dst.valueType := getPrimitiveType(AVT_REAL);
inc(pos);
end;
LITR_BYTE: begin
dst.value.asByte := source.getLexemeByte(pos);
dst.valueType := getPrimitiveType(AVT_BYTE);
inc(pos);
end;
LITR_SHORT: begin
dst.value.asShort := source.getLexemeShort(pos);
dst.valueType := getPrimitiveType(AVT_SHORT);
inc(pos);
end;
LITR_INT: begin
dst.value.asInt := source.getLexemeInt(pos);
dst.valueType := getPrimitiveType(AVT_INT);
inc(pos);
end;
LITR_LONG: begin
dst.value.asLong := source.getLexemeLong(pos);
dst.valueType := getPrimitiveType(AVT_LONG);
inc(pos);
end;
LITR_FLOAT: begin
dst.value.asFloat := source.getLexemeFloat(pos);
dst.valueType := getPrimitiveType(AVT_FLOAT);
inc(pos);
end;
LITR_DOUBLE: begin
dst.value.asDouble := source.getLexemeDouble(pos);
dst.valueType := getPrimitiveType(AVT_DOUBLE);
inc(pos);
end
else
raise AVTCompilerException.create('Error in expression', source, pos);
end;
result := parsePostfix(dst, typeRef, source, pos);
end;
function AVTConstantExpression.parsePrefix(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
var
i: int;
lexemeType: int;
operatorPos: int;
primitiveKind: int;
stack: Vector;
typeCastRef: AVTType;
typeOperandRef: AVTType;
item: AVTUnaryOperatorStackItem;
begin
stack := nil;
try
repeat
lexemeType := source.getLexemeType(pos);
case lexemeType of
OPER_BOOL_NOT, OPER_BIT_NOT, OPER_VECT_PACK, OPER_VECT_UNPCKL, OPER_VECT_UNPCKU: begin
if stack = nil then stack := Vector.create();
stack.append(ValueOfObject.create(AVTUnaryOperatorStackItem.create(pos, lexemeType)));
inc(pos);
end;
OPER_SCAL_ADD: begin
if stack = nil then stack := Vector.create();
stack.append(ValueOfObject.create(AVTUnaryOperatorStackItem.create(pos, OPER_SCAL_PLUS)));
inc(pos);
end;
OPER_SCAL_SUB: begin
if stack = nil then stack := Vector.create();
stack.append(ValueOfObject.create(AVTUnaryOperatorStackItem.create(pos, OPER_SCAL_MINUS)));
inc(pos);
end;
OPER_VECT_ADD: begin
if stack = nil then stack := Vector.create();
stack.append(ValueOfObject.create(AVTUnaryOperatorStackItem.create(pos, OPER_VECT_PLUS)));
inc(pos);
end;
OPER_VECT_SUB: begin
if stack = nil then stack := Vector.create();
stack.append(ValueOfObject.create(AVTUnaryOperatorStackItem.create(pos, OPER_VECT_MINUS)));
inc(pos);
end;
CHAR_PARENTH_OPENED: begin
operatorPos := pos;
typeCastRef := tryParseType(typeRef, source, pos + 1);
pos := source.position;
if (typeCastRef = nil) or (source.getLexemeType(pos) <> CHAR_PARENTH_CLOSED) then begin
pos := operatorPos;
break;
end;
if stack = nil then stack := Vector.create();
stack.append(ValueOfObject.create(AVTUnaryOperatorStackItem.create(operatorPos, OPER_TYPE_CAST, typeCastRef)));
inc(pos);
end
else
break;
end;
until false;
pos := parsePrimary(dst, typeRef, source, pos);
if stack <> nil then for i := stack.size() - 1 downto 0 do begin
item := stack.elementAt(i).objectValue() as AVTUnaryOperatorStackItem;
typeOperandRef := dst.valueType;
operatorPos := item.position;
case item.operatorKind of
OPER_BOOL_NOT: begin
if (typeOperandRef <> nil) and typeOperandRef.isBoolean() then begin
dst.value.asBoolean := not dst.value.asBoolean;
continue;
end;
raise AVTCompilerException.create('The operator ! is undefined for the argument type ' + itemToString(typeOperandRef), source, operatorPos);
end;
OPER_BIT_NOT: begin
if typeOperandRef is AVTTypePrimitive then begin
primitiveKind := AVTTypePrimitive(typeOperandRef).primitiveKind;
if primitiveKind = AVT_CHAR then begin
primitiveKind := AVT_INT;
dst.value.asInt := int(dst.value.asChar);
end;
case primitiveKind of
AVT_BYTE: begin
byteBitNot(dst, dst);
continue;
end;
AVT_BYTE2: begin
byte2BitNot(dst, dst);
continue;
end;
AVT_BYTE4: begin
byte4BitNot(dst, dst);
continue;
end;
AVT_BYTE8: begin
byte8BitNot(dst, dst);
continue;
end;
AVT_SHORT: begin
shortBitNot(dst, dst);
continue;
end;
AVT_SHORT2: begin
short2BitNot(dst, dst);
continue;
end;
AVT_SHORT4: begin
short4BitNot(dst, dst);
continue;
end;
AVT_SHORT8: begin
short8BitNot(dst, dst);
continue;
end;
AVT_INT: begin
intBitNot(dst, dst);
continue;
end;
AVT_INT2: begin
int2BitNot(dst, dst);
continue;
end;
AVT_INT4: begin
int4BitNot(dst, dst);
continue;
end;
AVT_INT8: begin
int8BitNot(dst, dst);
continue;
end;
AVT_LONG: begin
longBitNot(dst, dst);
continue;
end;
AVT_LONG2: begin
long2BitNot(dst, dst);
continue;
end;
AVT_LONG4: begin
long4BitNot(dst, dst);
continue;
end;
AVT_LONG8: begin
long8BitNot(dst, dst);
continue;
end;
end;
end;
raise AVTCompilerException.create('The operator ~ is undefined for the argument type ' + itemToString(typeOperandRef), source, operatorPos);
end;
OPER_SCAL_PLUS: begin
if typeOperandRef is AVTTypePrimitive then begin
primitiveKind := AVTTypePrimitive(typeOperandRef).primitiveKind;
if primitiveKind = AVT_CHAR then begin
primitiveKind := AVT_INT;
dst.value.asInt := int(dst.value.asChar);
end;
case primitiveKind of
AVT_BYTE: begin
byteScalPlus(dst, dst);
continue;
end;
AVT_BYTE2: begin
byte2ScalPlus(dst, dst);
continue;
end;
AVT_BYTE4: begin
byte4ScalPlus(dst, dst);
continue;
end;
AVT_BYTE8: begin
byte8ScalPlus(dst, dst);
continue;
end;
AVT_SHORT: begin
shortScalPlus(dst, dst);
continue;
end;
AVT_SHORT2: begin
short2ScalPlus(dst, dst);
continue;
end;
AVT_SHORT4: begin
short4ScalPlus(dst, dst);
continue;
end;
AVT_SHORT8: begin
short8ScalPlus(dst, dst);
continue;
end;
AVT_INT: begin
intScalPlus(dst, dst);
continue;
end;
AVT_INT2: begin
int2ScalPlus(dst, dst);
continue;
end;
AVT_INT4: begin
int4ScalPlus(dst, dst);
continue;
end;
AVT_INT8: begin
int8ScalPlus(dst, dst);
continue;
end;
AVT_LONG: begin
longScalPlus(dst, dst);
continue;
end;
AVT_LONG2: begin
long2ScalPlus(dst, dst);
continue;
end;
AVT_LONG4: begin
long4ScalPlus(dst, dst);
continue;
end;
AVT_LONG8: begin
long8ScalPlus(dst, dst);
continue;
end;
AVT_FLOAT: begin
floatScalPlus(dst, dst);
continue;
end;
AVT_FLOAT2: begin
float2ScalPlus(dst, dst);
continue;
end;
AVT_FLOAT4: begin
float4ScalPlus(dst, dst);
continue;
end;
AVT_FLOAT8: begin
float8ScalPlus(dst, dst);
continue;
end;
AVT_DOUBLE: begin
doubleScalPlus(dst, dst);
continue;
end;
AVT_DOUBLE2: begin
double2ScalPlus(dst, dst);
continue;
end;
AVT_DOUBLE4: begin
double4ScalPlus(dst, dst);
continue;
end;
AVT_DOUBLE8: begin
double8ScalPlus(dst, dst);
continue;
end;
AVT_REAL: begin
realScalPlus(dst, dst);
continue;
end;
end;
end;
raise AVTCompilerException.create('The operator + is undefined for the argument type ' + itemToString(typeOperandRef), source, operatorPos);
end;
OPER_SCAL_MINUS: begin
if typeOperandRef is AVTTypePrimitive then begin
primitiveKind := AVTTypePrimitive(typeOperandRef).primitiveKind;
if primitiveKind = AVT_CHAR then begin
primitiveKind := AVT_INT;
dst.value.asInt := int(dst.value.asChar);
end;
case primitiveKind of
AVT_BYTE: begin
byteScalMinus(dst, dst);
continue;
end;
AVT_BYTE2: begin
byte2ScalMinus(dst, dst);
continue;
end;
AVT_BYTE4: begin
byte4ScalMinus(dst, dst);
continue;
end;
AVT_BYTE8: begin
byte8ScalMinus(dst, dst);
continue;
end;
AVT_SHORT: begin
shortScalMinus(dst, dst);
continue;
end;
AVT_SHORT2: begin
short2ScalMinus(dst, dst);
continue;
end;
AVT_SHORT4: begin
short4ScalMinus(dst, dst);
continue;
end;
AVT_SHORT8: begin
short8ScalMinus(dst, dst);
continue;
end;
AVT_INT: begin
intScalMinus(dst, dst);
continue;
end;
AVT_INT2: begin
int2ScalMinus(dst, dst);
continue;
end;
AVT_INT4: begin
int4ScalMinus(dst, dst);
continue;
end;
AVT_INT8: begin
int8ScalMinus(dst, dst);
continue;
end;
AVT_LONG: begin
longScalMinus(dst, dst);
continue;
end;
AVT_LONG2: begin
long2ScalMinus(dst, dst);
continue;
end;
AVT_LONG4: begin
long4ScalMinus(dst, dst);
continue;
end;
AVT_LONG8: begin
long8ScalMinus(dst, dst);
continue;
end;
AVT_FLOAT: begin
floatScalMinus(dst, dst);
continue;
end;
AVT_FLOAT2: begin
float2ScalMinus(dst, dst);
continue;
end;
AVT_FLOAT4: begin
float4ScalMinus(dst, dst);
continue;
end;
AVT_FLOAT8: begin
float8ScalMinus(dst, dst);
continue;
end;
AVT_DOUBLE: begin
doubleScalMinus(dst, dst);
continue;
end;
AVT_DOUBLE2: begin
double2ScalMinus(dst, dst);
continue;
end;
AVT_DOUBLE4: begin
double4ScalMinus(dst, dst);
continue;
end;
AVT_DOUBLE8: begin
double8ScalMinus(dst, dst);
continue;
end;
AVT_REAL: begin
realScalMinus(dst, dst);
continue;
end;
end;
end;
raise AVTCompilerException.create('The operator - is undefined for the argument type ' + itemToString(typeOperandRef), source, operatorPos);
end;
OPER_VECT_PACK: begin
if typeOperandRef is AVTTypePrimitive then begin
primitiveKind := AVTTypePrimitive(typeOperandRef).primitiveKind;
if primitiveKind = AVT_CHAR then begin
primitiveKind := AVT_INT;
dst.value.asInt := int(dst.value.asChar);
end;
case primitiveKind of
AVT_BYTE: begin
castByte8ToShort8(dst, dst, AVT_SHORT);
shortVectPack(dst, dst);
continue;
end;
AVT_BYTE2: begin
castByte8ToShort8(dst, dst, AVT_SHORT2);
short2VectPack(dst, dst);
continue;
end;
AVT_BYTE4: begin
castByte8ToShort8(dst, dst, AVT_SHORT4);
short4VectPack(dst, dst);
continue;
end;
AVT_BYTE8: begin
castByte8ToShort8(dst, dst, AVT_SHORT8);
short8VectPack(dst, dst);
continue;
end;
AVT_SHORT: begin
shortVectPack(dst, dst);
continue;
end;
AVT_SHORT2: begin
short2VectPack(dst, dst);
continue;
end;
AVT_SHORT4: begin
short4VectPack(dst, dst);
continue;
end;
AVT_SHORT8: begin
short8VectPack(dst, dst);
continue;
end;
AVT_INT: begin
intVectPack(dst, dst);
continue;
end;
AVT_INT2: begin
int2VectPack(dst, dst);
continue;
end;
AVT_INT4: begin
int4VectPack(dst, dst);
continue;
end;
AVT_INT8: begin
int8VectPack(dst, dst);
continue;
end;
AVT_LONG: begin
longVectPack(dst, dst);
continue;
end;
AVT_LONG2: begin
long2VectPack(dst, dst);
continue;
end;
AVT_LONG4: begin
long4VectPack(dst, dst);
continue;
end;
AVT_LONG8: begin
long8VectPack(dst, dst);
continue;
end;
end;
end;
raise AVTCompilerException.create('The operator @@@@ is undefined for the argument type ' + itemToString(typeOperandRef), source, operatorPos);
end;
OPER_VECT_UNPCKL: begin
if typeOperandRef is AVTTypePrimitive then begin
primitiveKind := AVTTypePrimitive(typeOperandRef).primitiveKind;
if primitiveKind = AVT_CHAR then begin
primitiveKind := AVT_INT;
dst.value.asInt := int(dst.value.asChar);
end;
case primitiveKind of
AVT_BYTE: begin
byteVectUnpckl(dst, dst);
continue;
end;
AVT_BYTE2: begin
byte2VectUnpckl(dst, dst);
continue;
end;
AVT_BYTE4: begin
byte4VectUnpckl(dst, dst);
continue;
end;
AVT_BYTE8: begin
byte8VectUnpckl(dst, dst);
continue;
end;
AVT_SHORT: begin
shortVectUnpckl(dst, dst);
continue;
end;
AVT_SHORT2: begin
short2VectUnpckl(dst, dst);
continue;
end;
AVT_SHORT4: begin
short4VectUnpckl(dst, dst);
continue;
end;
AVT_SHORT8: begin
short8VectUnpckl(dst, dst);
continue;
end;
AVT_INT: begin
intVectUnpckl(dst, dst);
continue;
end;
AVT_INT2: begin
int2VectUnpckl(dst, dst);
continue;
end;
AVT_INT4: begin
int4VectUnpckl(dst, dst);
continue;
end;
AVT_INT8: begin
int8VectUnpckl(dst, dst);
continue;
end;
end;
end;
raise AVTCompilerException.create('The operator #### is undefined for the argument type ' + itemToString(typeOperandRef), source, operatorPos);
end;
OPER_VECT_UNPCKU: begin
if typeOperandRef is AVTTypePrimitive then begin
primitiveKind := AVTTypePrimitive(typeOperandRef).primitiveKind;
if primitiveKind = AVT_CHAR then begin
primitiveKind := AVT_INT;
dst.value.asInt := int(dst.value.asChar);
end;
case primitiveKind of
AVT_BYTE: begin
byteVectUnpcku(dst, dst);
continue;
end;
AVT_BYTE2: begin
byte2VectUnpcku(dst, dst);
continue;
end;
AVT_BYTE4: begin
byte4VectUnpcku(dst, dst);
continue;
end;
AVT_BYTE8: begin
byte8VectUnpcku(dst, dst);
continue;
end;
AVT_SHORT: begin
shortVectUnpcku(dst, dst);
continue;
end;
AVT_SHORT2: begin
short2VectUnpcku(dst, dst);
continue;
end;
AVT_SHORT4: begin
short4VectUnpcku(dst, dst);
continue;
end;
AVT_SHORT8: begin
short8VectUnpcku(dst, dst);
continue;
end;
AVT_INT: begin
intVectUnpcku(dst, dst);
continue;
end;
AVT_INT2: begin
int2VectUnpcku(dst, dst);
continue;
end;
AVT_INT4: begin
int4VectUnpcku(dst, dst);
continue;
end;
AVT_INT8: begin
int8VectUnpcku(dst, dst);
continue;
end;
end;
end;
raise AVTCompilerException.create('The operator ^^^^ is undefined for the argument type ' + itemToString(typeOperandRef), source, operatorPos);
end;
OPER_VECT_PLUS: begin
if typeOperandRef is AVTTypePrimitive then begin
primitiveKind := AVTTypePrimitive(typeOperandRef).primitiveKind;
if primitiveKind = AVT_CHAR then begin
primitiveKind := AVT_INT;
dst.value.asInt := int(dst.value.asChar);
end;
case primitiveKind of
AVT_BYTE: begin
byteVectPlus(dst, dst);
continue;
end;
AVT_BYTE2: begin
byte2VectPlus(dst, dst);
continue;
end;
AVT_BYTE4: begin
byte4VectPlus(dst, dst);
continue;
end;
AVT_BYTE8: begin
byte8VectPlus(dst, dst);
continue;
end;
AVT_SHORT: begin
shortVectPlus(dst, dst);
continue;
end;
AVT_SHORT2: begin
short2VectPlus(dst, dst);
continue;
end;
AVT_SHORT4: begin
short4VectPlus(dst, dst);
continue;
end;
AVT_SHORT8: begin
short8VectPlus(dst, dst);
continue;
end;
AVT_INT: begin
intVectPlus(dst, dst);
continue;
end;
AVT_INT2: begin
int2VectPlus(dst, dst);
continue;
end;
AVT_INT4: begin
int4VectPlus(dst, dst);
continue;
end;
AVT_INT8: begin
int8VectPlus(dst, dst);
continue;
end;
AVT_LONG: begin
longVectPlus(dst, dst);
continue;
end;
AVT_LONG2: begin
long2VectPlus(dst, dst);
continue;
end;
AVT_LONG4: begin
long4VectPlus(dst, dst);
continue;
end;
AVT_LONG8: begin
long8VectPlus(dst, dst);
continue;
end;
AVT_FLOAT: begin
floatVectPlus(dst, dst);
continue;
end;
AVT_FLOAT2: begin
float2VectPlus(dst, dst);
continue;
end;
AVT_FLOAT4: begin
float4VectPlus(dst, dst);
continue;
end;
AVT_FLOAT8: begin
float8VectPlus(dst, dst);
continue;
end;
AVT_DOUBLE: begin
doubleVectPlus(dst, dst);
continue;
end;
AVT_DOUBLE2: begin
double2VectPlus(dst, dst);
continue;
end;
AVT_DOUBLE4: begin
double4VectPlus(dst, dst);
continue;
end;
AVT_DOUBLE8: begin
double8VectPlus(dst, dst);
continue;
end;
end;
end;
raise AVTCompilerException.create('The operator ++++ is undefined for the argument type ' + itemToString(typeOperandRef), source, operatorPos);
end;
OPER_VECT_MINUS: begin
if typeOperandRef is AVTTypePrimitive then begin
primitiveKind := AVTTypePrimitive(typeOperandRef).primitiveKind;
if primitiveKind = AVT_CHAR then begin
primitiveKind := AVT_INT;
dst.value.asInt := int(dst.value.asChar);
end;
case primitiveKind of
AVT_BYTE: begin
byteVectMinus(dst, dst);
continue;
end;
AVT_BYTE2: begin
byte2VectMinus(dst, dst);
continue;
end;
AVT_BYTE4: begin
byte4VectMinus(dst, dst);
continue;
end;
AVT_BYTE8: begin
byte8VectMinus(dst, dst);
continue;
end;
AVT_SHORT: begin
shortVectMinus(dst, dst);
continue;
end;
AVT_SHORT2: begin
short2VectMinus(dst, dst);
continue;
end;
AVT_SHORT4: begin
short4VectMinus(dst, dst);
continue;
end;
AVT_SHORT8: begin
short8VectMinus(dst, dst);
continue;
end;
AVT_INT: begin
intVectMinus(dst, dst);
continue;
end;
AVT_INT2: begin
int2VectMinus(dst, dst);
continue;
end;
AVT_INT4: begin
int4VectMinus(dst, dst);
continue;
end;
AVT_INT8: begin
int8VectMinus(dst, dst);
continue;
end;
AVT_LONG: begin
longVectMinus(dst, dst);
continue;
end;
AVT_LONG2: begin
long2VectMinus(dst, dst);
continue;
end;
AVT_LONG4: begin
long4VectMinus(dst, dst);
continue;
end;
AVT_LONG8: begin
long8VectMinus(dst, dst);
continue;
end;
AVT_FLOAT: begin
floatVectMinus(dst, dst);
continue;
end;
AVT_FLOAT2: begin
float2VectMinus(dst, dst);
continue;
end;
AVT_FLOAT4: begin
float4VectMinus(dst, dst);
continue;
end;
AVT_FLOAT8: begin
float8VectMinus(dst, dst);
continue;
end;
AVT_DOUBLE: begin
doubleVectMinus(dst, dst);
continue;
end;
AVT_DOUBLE2: begin
double2VectMinus(dst, dst);
continue;
end;
AVT_DOUBLE4: begin
double4VectMinus(dst, dst);
continue;
end;
AVT_DOUBLE8: begin
double8VectMinus(dst, dst);
continue;
end;
end;
end;
raise AVTCompilerException.create('The operator ---- is undefined for the argument type ' + itemToString(typeOperandRef), source, operatorPos);
end;
OPER_TYPE_CAST: begin
typeCastRef := item.typeCast;
if typeOperandRef = nil then begin
if typeCastRef is AVTTypeStructured then begin
dst.valueType := typeCastRef;
continue;
end;
end else begin
if typeOperandRef.isBoolean() and typeCastRef.isBoolean() then begin
continue;
end;
if typeOperandRef.isNumeric() and typeCastRef.isNumeric() then begin
cast(dst, dst, typeCastRef as AVTTypePrimitive);
continue;
end;
if (typeOperandRef is AVTTypeStructured) and (typeCastRef is AVTTypeStructured) and typeCastRef.isAssignableFrom(typeOperandRef) then begin
dst.valueType := typeCastRef;
continue;
end;
end;
raise AVTCompilerException.create('Can not cast from ' + itemToString(typeOperandRef) + ' to ' + itemToString(typeCastRef), source, operatorPos);
end;
end;
end;
finally
stack.free();
end;
result := pos;
end;
function AVTConstantExpression.parseMultiplicative(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
var
operatorPos: int;
op1: AVTConstant;
typeCommonRef: AVTType;
typeOperand0Ref: AVTType;
typeOperand1Ref: AVTType;
begin
pos := parsePrefix(dst, typeRef, source, pos);
repeat
operatorPos := pos;
case source.getLexemeType(pos) of
OPER_SCAL_MUL: begin
op1 := AVTConstant.create();
try
pos := parsePrefix(op1, typeRef, source, pos + 1);
typeOperand0Ref := dst.valueType;
typeOperand1Ref := op1.valueType;
typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
if typeCommonRef is AVTTypePrimitive then begin
cast(dst, dst, AVTTypePrimitive(typeCommonRef));
cast(op1, op1, AVTTypePrimitive(typeCommonRef));
case AVTTypePrimitive(typeCommonRef).primitiveKind of
AVT_BYTE: begin
byteScalMul(dst, dst, op1);
continue;
end;
AVT_BYTE2: begin
byte2ScalMul(dst, dst, op1);
continue;
end;
AVT_BYTE4: begin
byte4ScalMul(dst, dst, op1);
continue;
end;
AVT_BYTE8: begin
byte8ScalMul(dst, dst, op1);
continue;
end;
AVT_SHORT: begin
shortScalMul(dst, dst, op1);
continue;
end;
AVT_SHORT2: begin
short2ScalMul(dst, dst, op1);
continue;
end;
AVT_SHORT4: begin
short4ScalMul(dst, dst, op1);
continue;
end;
AVT_SHORT8: begin
short8ScalMul(dst, dst, op1);
continue;
end;
AVT_INT: begin
intScalMul(dst, dst, op1);
continue;
end;
AVT_INT2: begin
int2ScalMul(dst, dst, op1);
continue;
end;
AVT_INT4: begin
int4ScalMul(dst, dst, op1);
continue;
end;
AVT_INT8: begin
int8ScalMul(dst, dst, op1);
continue;
end;
AVT_LONG: begin
longScalMul(dst, dst, op1);
continue;
end;
AVT_LONG2: begin
long2ScalMul(dst, dst, op1);
continue;
end;
AVT_LONG4: begin
long4ScalMul(dst, dst, op1);
continue;
end;
AVT_LONG8: begin
long8ScalMul(dst, dst, op1);
continue;
end;
AVT_FLOAT: begin
floatScalMul(dst, dst, op1);
continue;
end;
AVT_FLOAT2: begin
float2ScalMul(dst, dst, op1);
continue;
end;
AVT_FLOAT4: begin
float4ScalMul(dst, dst, op1);
continue;
end;
AVT_FLOAT8: begin
float8ScalMul(dst, dst, op1);
continue;
end;
AVT_DOUBLE: begin
doubleScalMul(dst, dst, op1);
continue;
end;
AVT_DOUBLE2: begin
double2ScalMul(dst, dst, op1);
continue;
end;
AVT_DOUBLE4: begin
double4ScalMul(dst, dst, op1);
continue;
end;
AVT_DOUBLE8: begin
double8ScalMul(dst, dst, op1);
continue;
end;
AVT_REAL: begin
realScalMul(dst, dst, op1);
continue;
end;
end;
end;
finally
op1.free();
end;
raise AVTCompilerException.create('The operator * is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
end;
OPER_SCAL_DIV: begin
op1 := AVTConstant.create();
try
pos := parsePrefix(op1, typeRef, source, pos + 1);
typeOperand0Ref := dst.valueType;
typeOperand1Ref := op1.valueType;
typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
if typeCommonRef is AVTTypePrimitive then begin
cast(dst, dst, AVTTypePrimitive(typeCommonRef));
cast(op1, op1, AVTTypePrimitive(typeCommonRef));
case AVTTypePrimitive(typeCommonRef).primitiveKind of
AVT_BYTE: begin
if op1.value.asByte = 0 then begin
raise AVTCompilerException.create('Integer constant division by zero error', source, operatorPos);
end;
byteScalDiv(dst, dst, op1);
continue;
end;
AVT_SHORT: begin
if op1.value.asShort = 0 then begin
raise AVTCompilerException.create('Integer constant division by zero error', source, operatorPos);
end;
shortScalDiv(dst, dst, op1);
continue;
end;
AVT_INT: begin
if op1.value.asInt = 0 then begin
raise AVTCompilerException.create('Integer constant division by zero error', source, operatorPos);
end;
intScalDiv(dst, dst, op1);
continue;
end;
AVT_LONG: begin
if op1.value.asLong = 0 then begin
raise AVTCompilerException.create('Integer constant division by zero error', source, operatorPos);
end;
longScalDiv(dst, dst, op1);
continue;
end;
AVT_FLOAT: begin
floatScalDiv(dst, dst, op1);
continue;
end;
AVT_FLOAT2: begin
float2ScalDiv(dst, dst, op1);
continue;
end;
AVT_FLOAT4: begin
float4ScalDiv(dst, dst, op1);
continue;
end;
AVT_FLOAT8: begin
float8ScalDiv(dst, dst, op1);
continue;
end;
AVT_DOUBLE: begin
doubleScalDiv(dst, dst, op1);
continue;
end;
AVT_DOUBLE2: begin
double2ScalDiv(dst, dst, op1);
continue;
end;
AVT_DOUBLE4: begin
double4ScalDiv(dst, dst, op1);
continue;
end;
AVT_DOUBLE8: begin
double8ScalDiv(dst, dst, op1);
continue;
end;
AVT_REAL: begin
realScalDiv(dst, dst, op1);
continue;
end;
end;
end;
finally
op1.free();
end;
raise AVTCompilerException.create('The operator / is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
end;
OPER_SCAL_DIVU: begin
op1 := AVTConstant.create();
try
pos := parsePrefix(op1, typeRef, source, pos + 1);
typeOperand0Ref := dst.valueType;
typeOperand1Ref := op1.valueType;
typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
if typeCommonRef is AVTTypePrimitive then begin
cast(dst, dst, AVTTypePrimitive(typeCommonRef));
cast(op1, op1, AVTTypePrimitive(typeCommonRef));
case AVTTypePrimitive(typeCommonRef).primitiveKind of
AVT_BYTE: begin
if op1.value.asByte = 0 then begin
raise AVTCompilerException.create('Integer constant division by zero error', source, operatorPos);
end;
byteScalDivu(dst, dst, op1);
continue;
end;
AVT_SHORT: begin
if op1.value.asShort = 0 then begin
raise AVTCompilerException.create('Integer constant division by zero error', source, operatorPos);
end;
shortScalDivu(dst, dst, op1);
continue;
end;
AVT_INT: begin
if op1.value.asInt = 0 then begin
raise AVTCompilerException.create('Integer constant division by zero error', source, operatorPos);
end;
intScalDivu(dst, dst, op1);
continue;
end;
AVT_LONG: begin
if op1.value.asLong = 0 then begin
raise AVTCompilerException.create('Integer constant division by zero error', source, operatorPos);
end;
longScalDivu(dst, dst, op1);
continue;
end;
AVT_FLOAT: begin
floatScalDivu(dst, dst, op1);
continue;
end;
AVT_FLOAT2: begin
float2ScalDivu(dst, dst, op1);
continue;
end;
AVT_FLOAT4: begin
float4ScalDivu(dst, dst, op1);
continue;
end;
AVT_FLOAT8: begin
float8ScalDivu(dst, dst, op1);
continue;
end;
AVT_DOUBLE: begin
doubleScalDivu(dst, dst, op1);
continue;
end;
AVT_DOUBLE2: begin
double2ScalDivu(dst, dst, op1);
continue;
end;
AVT_DOUBLE4: begin
double4ScalDivu(dst, dst, op1);
continue;
end;
AVT_DOUBLE8: begin
double8ScalDivu(dst, dst, op1);
continue;
end;
AVT_REAL: begin
realScalDivu(dst, dst, op1);
continue;
end;
end;
end;
finally
op1.free();
end;
raise AVTCompilerException.create('The operator // is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
end;
OPER_SCAL_REM: begin
op1 := AVTConstant.create();
try
pos := parsePrefix(op1, typeRef, source, pos + 1);
typeOperand0Ref := dst.valueType;
typeOperand1Ref := op1.valueType;
typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
if typeCommonRef is AVTTypePrimitive then begin
cast(dst, dst, AVTTypePrimitive(typeCommonRef));
cast(op1, op1, AVTTypePrimitive(typeCommonRef));
case AVTTypePrimitive(typeCommonRef).primitiveKind of
AVT_BYTE: begin
if op1.value.asByte = 0 then begin
raise AVTCompilerException.create('Integer constant division by zero error', source, operatorPos);
end;
byteScalRem(dst, dst, op1);
continue;
end;
AVT_SHORT: begin
if op1.value.asShort = 0 then begin
raise AVTCompilerException.create('Integer constant division by zero error', source, operatorPos);
end;
shortScalRem(dst, dst, op1);
continue;
end;
AVT_INT: begin
if op1.value.asInt = 0 then begin
raise AVTCompilerException.create('Integer constant division by zero error', source, operatorPos);
end;
intScalRem(dst, dst, op1);
continue;
end;
AVT_LONG: begin
if op1.value.asLong = 0 then begin
raise AVTCompilerException.create('Integer constant division by zero error', source, operatorPos);
end;
longScalRem(dst, dst, op1);
continue;
end;
AVT_FLOAT: begin
floatScalRem(dst, dst, op1);
continue;
end;
AVT_DOUBLE: begin
doubleScalRem(dst, dst, op1);
continue;
end;
AVT_REAL: begin
realScalRem(dst, dst, op1);
continue;
end;
end;
end;
finally
op1.free();
end;
raise AVTCompilerException.create('The operator % is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
end;
OPER_SCAL_REMU: begin
op1 := AVTConstant.create();
try
pos := parsePrefix(op1, typeRef, source, pos + 1);
typeOperand0Ref := dst.valueType;
typeOperand1Ref := op1.valueType;
typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
if typeCommonRef is AVTTypePrimitive then begin
cast(dst, dst, AVTTypePrimitive(typeCommonRef));
cast(op1, op1, AVTTypePrimitive(typeCommonRef));
case AVTTypePrimitive(typeCommonRef).primitiveKind of
AVT_BYTE: begin
if op1.value.asByte = 0 then begin
raise AVTCompilerException.create('Integer constant division by zero error', source, operatorPos);
end;
byteScalRemu(dst, dst, op1);
continue;
end;
AVT_SHORT: begin
if op1.value.asShort = 0 then begin
raise AVTCompilerException.create('Integer constant division by zero error', source, operatorPos);
end;
shortScalRemu(dst, dst, op1);
continue;
end;
AVT_INT: begin
if op1.value.asInt = 0 then begin
raise AVTCompilerException.create('Integer constant division by zero error', source, operatorPos);
end;
intScalRemu(dst, dst, op1);
continue;
end;
AVT_LONG: begin
if op1.value.asLong = 0 then begin
raise AVTCompilerException.create('Integer constant division by zero error', source, operatorPos);
end;
longScalRemu(dst, dst, op1);
continue;
end;
AVT_FLOAT: begin
floatScalRemu(dst, dst, op1);
continue;
end;
AVT_DOUBLE: begin
doubleScalRemu(dst, dst, op1);
continue;
end;
AVT_REAL: begin
realScalRemu(dst, dst, op1);
continue;
end;
end;
end;
finally
op1.free();
end;
raise AVTCompilerException.create('The operator %% is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
end;
OPER_VECT_MUL: begin
op1 := AVTConstant.create();
try
pos := parsePrefix(op1, typeRef, source, pos + 1);
typeOperand0Ref := dst.valueType;
typeOperand1Ref := op1.valueType;
typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
if typeCommonRef is AVTTypePrimitive then begin
cast(dst, dst, AVTTypePrimitive(typeCommonRef));
cast(op1, op1, AVTTypePrimitive(typeCommonRef));
case AVTTypePrimitive(typeCommonRef).primitiveKind of
AVT_BYTE: begin
byteVectMul(dst, dst, op1);
continue;
end;
AVT_BYTE2: begin
byte2VectMul(dst, dst, op1);
continue;
end;
AVT_BYTE4: begin
byte4VectMul(dst, dst, op1);
continue;
end;
AVT_BYTE8: begin
byte8VectMul(dst, dst, op1);
continue;
end;
AVT_SHORT: begin
shortVectMul(dst, dst, op1);
continue;
end;
AVT_SHORT2: begin
short2VectMul(dst, dst, op1);
continue;
end;
AVT_SHORT4: begin
short4VectMul(dst, dst, op1);
continue;
end;
AVT_SHORT8: begin
short8VectMul(dst, dst, op1);
continue;
end;
AVT_INT: begin
intVectMul(dst, dst, op1);
continue;
end;
AVT_INT2: begin
int2VectMul(dst, dst, op1);
continue;
end;
AVT_INT4: begin
int4VectMul(dst, dst, op1);
continue;
end;
AVT_INT8: begin
int8VectMul(dst, dst, op1);
continue;
end;
AVT_LONG: begin
longVectMul(dst, dst, op1);
continue;
end;
AVT_LONG2: begin
long2VectMul(dst, dst, op1);
continue;
end;
AVT_LONG4: begin
long4VectMul(dst, dst, op1);
continue;
end;
AVT_LONG8: begin
long8VectMul(dst, dst, op1);
continue;
end;
AVT_FLOAT: begin
floatVectMul(dst, dst, op1);
continue;
end;
AVT_FLOAT2: begin
float2VectMul(dst, dst, op1);
continue;
end;
AVT_FLOAT4: begin
float4VectMul(dst, dst, op1);
continue;
end;
AVT_FLOAT8: begin
float8VectMul(dst, dst, op1);
continue;
end;
AVT_DOUBLE: begin
doubleVectMul(dst, dst, op1);
continue;
end;
AVT_DOUBLE2: begin
double2VectMul(dst, dst, op1);
continue;
end;
AVT_DOUBLE4: begin
double4VectMul(dst, dst, op1);
continue;
end;
AVT_DOUBLE8: begin
double8VectMul(dst, dst, op1);
continue;
end;
end;
end;
finally
op1.free();
end;
raise AVTCompilerException.create('The operator **** is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
end;
OPER_VECT_MULS: begin
op1 := AVTConstant.create();
try
pos := parsePrefix(op1, typeRef, source, pos + 1);
typeOperand0Ref := dst.valueType;
typeOperand1Ref := op1.valueType;
typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
if typeCommonRef is AVTTypePrimitive then begin
cast(dst, dst, AVTTypePrimitive(typeCommonRef));
cast(op1, op1, AVTTypePrimitive(typeCommonRef));
case AVTTypePrimitive(typeCommonRef).primitiveKind of
AVT_BYTE: begin
byteVectMuls(dst, dst, op1);
continue;
end;
AVT_BYTE2: begin
byte2VectMuls(dst, dst, op1);
continue;
end;
AVT_BYTE4: begin
byte4VectMuls(dst, dst, op1);
continue;
end;
AVT_BYTE8: begin
byte8VectMuls(dst, dst, op1);
continue;
end;
AVT_SHORT: begin
shortVectMuls(dst, dst, op1);
continue;
end;
AVT_SHORT2: begin
short2VectMuls(dst, dst, op1);
continue;
end;
AVT_SHORT4: begin
short4VectMuls(dst, dst, op1);
continue;
end;
AVT_SHORT8: begin
short8VectMuls(dst, dst, op1);
continue;
end;
end;
end;
finally
op1.free();
end;
raise AVTCompilerException.create('The operator |**| is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
end;
OPER_VECT_MULU: begin
op1 := AVTConstant.create();
try
pos := parsePrefix(op1, typeRef, source, pos + 1);
typeOperand0Ref := dst.valueType;
typeOperand1Ref := op1.valueType;
typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
if typeCommonRef is AVTTypePrimitive then begin
cast(dst, dst, AVTTypePrimitive(typeCommonRef));
cast(op1, op1, AVTTypePrimitive(typeCommonRef));
case AVTTypePrimitive(typeCommonRef).primitiveKind of
AVT_BYTE: begin
byteVectMulu(dst, dst, op1);
continue;
end;
AVT_BYTE2: begin
byte2VectMulu(dst, dst, op1);
continue;
end;
AVT_BYTE4: begin
byte4VectMulu(dst, dst, op1);
continue;
end;
AVT_BYTE8: begin
byte8VectMulu(dst, dst, op1);
continue;
end;
AVT_SHORT: begin
shortVectMulu(dst, dst, op1);
continue;
end;
AVT_SHORT2: begin
short2VectMulu(dst, dst, op1);
continue;
end;
AVT_SHORT4: begin
short4VectMulu(dst, dst, op1);
continue;
end;
AVT_SHORT8: begin
short8VectMulu(dst, dst, op1);
continue;
end;
end;
end;
finally
op1.free();
end;
raise AVTCompilerException.create('The operator #**# is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
end;
OPER_VECT_DIV: begin
op1 := AVTConstant.create();
try
pos := parsePrefix(op1, typeRef, source, pos + 1);
typeOperand0Ref := dst.valueType;
typeOperand1Ref := op1.valueType;
typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
if typeCommonRef is AVTTypePrimitive then begin
cast(dst, dst, AVTTypePrimitive(typeCommonRef));
cast(op1, op1, AVTTypePrimitive(typeCommonRef));
case AVTTypePrimitive(typeCommonRef).primitiveKind of
AVT_BYTE: begin
castByte8ToFloat8(dst, dst, AVT_FLOAT);
castByte8ToFloat8(op1, op1, AVT_FLOAT);
floatVectDiv(dst, dst, op1);
continue;
end;
AVT_BYTE2: begin
castByte8ToFloat8(dst, dst, AVT_FLOAT2);
castByte8ToFloat8(op1, op1, AVT_FLOAT2);
float2VectDiv(dst, dst, op1);
continue;
end;
AVT_BYTE4: begin
castByte8ToFloat8(dst, dst, AVT_FLOAT4);
castByte8ToFloat8(op1, op1, AVT_FLOAT4);
float4VectDiv(dst, dst, op1);
continue;
end;
AVT_BYTE8: begin
castByte8ToFloat8(dst, dst, AVT_FLOAT8);
castByte8ToFloat8(op1, op1, AVT_FLOAT8);
float8VectDiv(dst, dst, op1);
continue;
end;
AVT_SHORT: begin
castShort8ToFloat8(dst, dst, AVT_FLOAT);
castShort8ToFloat8(op1, op1, AVT_FLOAT);
floatVectDiv(dst, dst, op1);
continue;
end;
AVT_SHORT2: begin
castShort8ToFloat8(dst, dst, AVT_FLOAT2);
castShort8ToFloat8(op1, op1, AVT_FLOAT2);
float2VectDiv(dst, dst, op1);
continue;
end;
AVT_SHORT4: begin
castShort8ToFloat8(dst, dst, AVT_FLOAT4);
castShort8ToFloat8(op1, op1, AVT_FLOAT4);
float4VectDiv(dst, dst, op1);
continue;
end;
AVT_SHORT8: begin
castShort8ToFloat8(dst, dst, AVT_FLOAT8);
castShort8ToFloat8(op1, op1, AVT_FLOAT8);
float8VectDiv(dst, dst, op1);
continue;
end;
AVT_INT: begin
castInt8ToDouble8(dst, dst, AVT_DOUBLE);
castInt8ToDouble8(op1, op1, AVT_DOUBLE);
doubleVectDiv(dst, dst, op1);
continue;
end;
AVT_INT2: begin
castInt8ToDouble8(dst, dst, AVT_DOUBLE2);
castInt8ToDouble8(op1, op1, AVT_DOUBLE2);
double2VectDiv(dst, dst, op1);
continue;
end;
AVT_INT4: begin
castInt8ToDouble8(dst, dst, AVT_DOUBLE4);
castInt8ToDouble8(op1, op1, AVT_DOUBLE4);
double4VectDiv(dst, dst, op1);
continue;
end;
AVT_INT8: begin
castInt8ToDouble8(dst, dst, AVT_DOUBLE8);
castInt8ToDouble8(op1, op1, AVT_DOUBLE8);
double8VectDiv(dst, dst, op1);
continue;
end;
AVT_FLOAT: begin
floatVectDiv(dst, dst, op1);
continue;
end;
AVT_FLOAT2: begin
float2VectDiv(dst, dst, op1);
continue;
end;
AVT_FLOAT4: begin
float4VectDiv(dst, dst, op1);
continue;
end;
AVT_FLOAT8: begin
float8VectDiv(dst, dst, op1);
continue;
end;
AVT_DOUBLE: begin
doubleVectDiv(dst, dst, op1);
continue;
end;
AVT_DOUBLE2: begin
double2VectDiv(dst, dst, op1);
continue;
end;
AVT_DOUBLE4: begin
double4VectDiv(dst, dst, op1);
continue;
end;
AVT_DOUBLE8: begin
double8VectDiv(dst, dst, op1);
continue;
end;
end;
end;
finally
op1.free();
end;
raise AVTCompilerException.create('The operator //// is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
end
else
break;
end;
until false;
result := pos;
end;
function AVTConstantExpression.parseAdditive(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
var
operatorPos: int;
op1: AVTConstant;
typeStringRef: AVTType;
typeCommonRef: AVTType;
typeOperand0Ref: AVTType;
typeOperand1Ref: AVTType;
begin
pos := parseMultiplicative(dst, typeRef, source, pos);
repeat
operatorPos := pos;
case source.getLexemeType(pos) of
OPER_SCAL_ADD: begin
op1 := AVTConstant.create();
try
pos := parseMultiplicative(op1, typeRef, source, pos + 1);
typeOperand0Ref := dst.valueType;
typeOperand1Ref := op1.valueType;
typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
if typeCommonRef is AVTTypeStructured then begin
typeStringRef := getStringType();
if typeStringRef.isAssignableFrom(typeCommonRef) and not dst.value.isNull and not op1.value.isNull then begin
dst.value.asString := dst.value.asString + op1.value.asString;
dst.valueType := typeStringRef;
continue;
end;
end else
if typeCommonRef is AVTTypePrimitive then begin
cast(dst, dst, AVTTypePrimitive(typeCommonRef));
cast(op1, op1, AVTTypePrimitive(typeCommonRef));
case AVTTypePrimitive(typeCommonRef).primitiveKind of
AVT_BYTE: begin
byteScalAdd(dst, dst, op1);
continue;
end;
AVT_BYTE2: begin
byte2ScalAdd(dst, dst, op1);
continue;
end;
AVT_BYTE4: begin
byte4ScalAdd(dst, dst, op1);
continue;
end;
AVT_BYTE8: begin
byte8ScalAdd(dst, dst, op1);
continue;
end;
AVT_SHORT: begin
shortScalAdd(dst, dst, op1);
continue;
end;
AVT_SHORT2: begin
short2ScalAdd(dst, dst, op1);
continue;
end;
AVT_SHORT4: begin
short4ScalAdd(dst, dst, op1);
continue;
end;
AVT_SHORT8: begin
short8ScalAdd(dst, dst, op1);
continue;
end;
AVT_INT: begin
intScalAdd(dst, dst, op1);
continue;
end;
AVT_INT2: begin
int2ScalAdd(dst, dst, op1);
continue;
end;
AVT_INT4: begin
int4ScalAdd(dst, dst, op1);
continue;
end;
AVT_INT8: begin
int8ScalAdd(dst, dst, op1);
continue;
end;
AVT_LONG: begin
longScalAdd(dst, dst, op1);
continue;
end;
AVT_LONG2: begin
long2ScalAdd(dst, dst, op1);
continue;
end;
AVT_LONG4: begin
long4ScalAdd(dst, dst, op1);
continue;
end;
AVT_LONG8: begin
long8ScalAdd(dst, dst, op1);
continue;
end;
AVT_FLOAT: begin
floatScalAdd(dst, dst, op1);
continue;
end;
AVT_FLOAT2: begin
float2ScalAdd(dst, dst, op1);
continue;
end;
AVT_FLOAT4: begin
float4ScalAdd(dst, dst, op1);
continue;
end;
AVT_FLOAT8: begin
float8ScalAdd(dst, dst, op1);
continue;
end;
AVT_DOUBLE: begin
doubleScalAdd(dst, dst, op1);
continue;
end;
AVT_DOUBLE2: begin
double2ScalAdd(dst, dst, op1);
continue;
end;
AVT_DOUBLE4: begin
double4ScalAdd(dst, dst, op1);
continue;
end;
AVT_DOUBLE8: begin
double8ScalAdd(dst, dst, op1);
continue;
end;
AVT_REAL: begin
realScalAdd(dst, dst, op1);
continue;
end;
end;
end;
finally
op1.free();
end;
raise AVTCompilerException.create('The operator + is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
end;
OPER_SCAL_SUB: begin
op1 := AVTConstant.create();
try
pos := parseMultiplicative(op1, typeRef, source, pos + 1);
typeOperand0Ref := dst.valueType;
typeOperand1Ref := op1.valueType;
typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
if typeCommonRef is AVTTypePrimitive then begin
cast(dst, dst, AVTTypePrimitive(typeCommonRef));
cast(op1, op1, AVTTypePrimitive(typeCommonRef));
case AVTTypePrimitive(typeCommonRef).primitiveKind of
AVT_BYTE: begin
byteScalSub(dst, dst, op1);
continue;
end;
AVT_BYTE2: begin
byte2ScalSub(dst, dst, op1);
continue;
end;
AVT_BYTE4: begin
byte4ScalSub(dst, dst, op1);
continue;
end;
AVT_BYTE8: begin
byte8ScalSub(dst, dst, op1);
continue;
end;
AVT_SHORT: begin
shortScalSub(dst, dst, op1);
continue;
end;
AVT_SHORT2: begin
short2ScalSub(dst, dst, op1);
continue;
end;
AVT_SHORT4: begin
short4ScalSub(dst, dst, op1);
continue;
end;
AVT_SHORT8: begin
short8ScalSub(dst, dst, op1);
continue;
end;
AVT_INT: begin
intScalSub(dst, dst, op1);
continue;
end;
AVT_INT2: begin
int2ScalSub(dst, dst, op1);
continue;
end;
AVT_INT4: begin
int4ScalSub(dst, dst, op1);
continue;
end;
AVT_INT8: begin
int8ScalSub(dst, dst, op1);
continue;
end;
AVT_LONG: begin
longScalSub(dst, dst, op1);
continue;
end;
AVT_LONG2: begin
long2ScalSub(dst, dst, op1);
continue;
end;
AVT_LONG4: begin
long4ScalSub(dst, dst, op1);
continue;
end;
AVT_LONG8: begin
long8ScalSub(dst, dst, op1);
continue;
end;
AVT_FLOAT: begin
floatScalSub(dst, dst, op1);
continue;
end;
AVT_FLOAT2: begin
float2ScalSub(dst, dst, op1);
continue;
end;
AVT_FLOAT4: begin
float4ScalSub(dst, dst, op1);
continue;
end;
AVT_FLOAT8: begin
float8ScalSub(dst, dst, op1);
continue;
end;
AVT_DOUBLE: begin
doubleScalSub(dst, dst, op1);
continue;
end;
AVT_DOUBLE2: begin
double2ScalSub(dst, dst, op1);
continue;
end;
AVT_DOUBLE4: begin
double4ScalSub(dst, dst, op1);
continue;
end;
AVT_DOUBLE8: begin
double8ScalSub(dst, dst, op1);
continue;
end;
AVT_REAL: begin
realScalSub(dst, dst, op1);
continue;
end;
end;
end;
finally
op1.free();
end;
raise AVTCompilerException.create('The operator - is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
end;
OPER_VECT_ADD: begin
op1 := AVTConstant.create();
try
pos := parseMultiplicative(op1, typeRef, source, pos + 1);
typeOperand0Ref := dst.valueType;
typeOperand1Ref := op1.valueType;
typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
if typeCommonRef is AVTTypePrimitive then begin
cast(dst, dst, AVTTypePrimitive(typeCommonRef));
cast(op1, op1, AVTTypePrimitive(typeCommonRef));
case AVTTypePrimitive(typeCommonRef).primitiveKind of
AVT_BYTE: begin
byteVectAdd(dst, dst, op1);
continue;
end;
AVT_BYTE2: begin
byte2VectAdd(dst, dst, op1);
continue;
end;
AVT_BYTE4: begin
byte4VectAdd(dst, dst, op1);
continue;
end;
AVT_BYTE8: begin
byte8VectAdd(dst, dst, op1);
continue;
end;
AVT_SHORT: begin
shortVectAdd(dst, dst, op1);
continue;
end;
AVT_SHORT2: begin
short2VectAdd(dst, dst, op1);
continue;
end;
AVT_SHORT4: begin
short4VectAdd(dst, dst, op1);
continue;
end;
AVT_SHORT8: begin
short8VectAdd(dst, dst, op1);
continue;
end;
AVT_INT: begin
intVectAdd(dst, dst, op1);
continue;
end;
AVT_INT2: begin
int2VectAdd(dst, dst, op1);
continue;
end;
AVT_INT4: begin
int4VectAdd(dst, dst, op1);
continue;
end;
AVT_INT8: begin
int8VectAdd(dst, dst, op1);
continue;
end;
AVT_LONG: begin
longVectAdd(dst, dst, op1);
continue;
end;
AVT_LONG2: begin
long2VectAdd(dst, dst, op1);
continue;
end;
AVT_LONG4: begin
long4VectAdd(dst, dst, op1);
continue;
end;
AVT_LONG8: begin
long8VectAdd(dst, dst, op1);
continue;
end;
AVT_FLOAT: begin
floatVectAdd(dst, dst, op1);
continue;
end;
AVT_FLOAT2: begin
float2VectAdd(dst, dst, op1);
continue;
end;
AVT_FLOAT4: begin
float4VectAdd(dst, dst, op1);
continue;
end;
AVT_FLOAT8: begin
float8VectAdd(dst, dst, op1);
continue;
end;
AVT_DOUBLE: begin
doubleVectAdd(dst, dst, op1);
continue;
end;
AVT_DOUBLE2: begin
double2VectAdd(dst, dst, op1);
continue;
end;
AVT_DOUBLE4: begin
double4VectAdd(dst, dst, op1);
continue;
end;
AVT_DOUBLE8: begin
double8VectAdd(dst, dst, op1);
continue;
end;
end;
end;
finally
op1.free();
end;
raise AVTCompilerException.create('The operator ++++ is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
end;
OPER_VECT_ADDS: begin
op1 := AVTConstant.create();
try
pos := parseMultiplicative(op1, typeRef, source, pos + 1);
typeOperand0Ref := dst.valueType;
typeOperand1Ref := op1.valueType;
typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
if typeCommonRef is AVTTypePrimitive then begin
cast(dst, dst, AVTTypePrimitive(typeCommonRef));
cast(op1, op1, AVTTypePrimitive(typeCommonRef));
case AVTTypePrimitive(typeCommonRef).primitiveKind of
AVT_BYTE: begin
byteVectAdds(dst, dst, op1);
continue;
end;
AVT_BYTE2: begin
byte2VectAdds(dst, dst, op1);
continue;
end;
AVT_BYTE4: begin
byte4VectAdds(dst, dst, op1);
continue;
end;
AVT_BYTE8: begin
byte8VectAdds(dst, dst, op1);
continue;
end;
AVT_SHORT: begin
shortVectAdds(dst, dst, op1);
continue;
end;
AVT_SHORT2: begin
short2VectAdds(dst, dst, op1);
continue;
end;
AVT_SHORT4: begin
short4VectAdds(dst, dst, op1);
continue;
end;
AVT_SHORT8: begin
short8VectAdds(dst, dst, op1);
continue;
end;
end;
end;
finally
op1.free();
end;
raise AVTCompilerException.create('The operator |++| is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
end;
OPER_VECT_ADDU: begin
op1 := AVTConstant.create();
try
pos := parseMultiplicative(op1, typeRef, source, pos + 1);
typeOperand0Ref := dst.valueType;
typeOperand1Ref := op1.valueType;
typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
if typeCommonRef is AVTTypePrimitive then begin
cast(dst, dst, AVTTypePrimitive(typeCommonRef));
cast(op1, op1, AVTTypePrimitive(typeCommonRef));
case AVTTypePrimitive(typeCommonRef).primitiveKind of
AVT_BYTE: begin
byteVectAddu(dst, dst, op1);
continue;
end;
AVT_BYTE2: begin
byte2VectAddu(dst, dst, op1);
continue;
end;
AVT_BYTE4: begin
byte4VectAddu(dst, dst, op1);
continue;
end;
AVT_BYTE8: begin
byte8VectAddu(dst, dst, op1);
continue;
end;
AVT_SHORT: begin
shortVectAddu(dst, dst, op1);
continue;
end;
AVT_SHORT2: begin
short2VectAddu(dst, dst, op1);
continue;
end;
AVT_SHORT4: begin
short4VectAddu(dst, dst, op1);
continue;
end;
AVT_SHORT8: begin
short8VectAddu(dst, dst, op1);
continue;
end;
end;
end;
finally
op1.free();
end;
raise AVTCompilerException.create('The operator #++# is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
end;
OPER_VECT_SUB: begin
op1 := AVTConstant.create();
try
pos := parseMultiplicative(op1, typeRef, source, pos + 1);
typeOperand0Ref := dst.valueType;
typeOperand1Ref := op1.valueType;
typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
if typeCommonRef is AVTTypePrimitive then begin
cast(dst, dst, AVTTypePrimitive(typeCommonRef));
cast(op1, op1, AVTTypePrimitive(typeCommonRef));
case AVTTypePrimitive(typeCommonRef).primitiveKind of
AVT_BYTE: begin
byteVectSub(dst, dst, op1);
continue;
end;
AVT_BYTE2: begin
byte2VectSub(dst, dst, op1);
continue;
end;
AVT_BYTE4: begin
byte4VectSub(dst, dst, op1);
continue;
end;
AVT_BYTE8: begin
byte8VectSub(dst, dst, op1);
continue;
end;
AVT_SHORT: begin
shortVectSub(dst, dst, op1);
continue;
end;
AVT_SHORT2: begin
short2VectSub(dst, dst, op1);
continue;
end;
AVT_SHORT4: begin
short4VectSub(dst, dst, op1);
continue;
end;
AVT_SHORT8: begin
short8VectSub(dst, dst, op1);
continue;
end;
AVT_INT: begin
intVectSub(dst, dst, op1);
continue;
end;
AVT_INT2: begin
int2VectSub(dst, dst, op1);
continue;
end;
AVT_INT4: begin
int4VectSub(dst, dst, op1);
continue;
end;
AVT_INT8: begin
int8VectSub(dst, dst, op1);
continue;
end;
AVT_LONG: begin
longVectSub(dst, dst, op1);
continue;
end;
AVT_LONG2: begin
long2VectSub(dst, dst, op1);
continue;
end;
AVT_LONG4: begin
long4VectSub(dst, dst, op1);
continue;
end;
AVT_LONG8: begin
long8VectSub(dst, dst, op1);
continue;
end;
AVT_FLOAT: begin
floatVectSub(dst, dst, op1);
continue;
end;
AVT_FLOAT2: begin
float2VectSub(dst, dst, op1);
continue;
end;
AVT_FLOAT4: begin
float4VectSub(dst, dst, op1);
continue;
end;
AVT_FLOAT8: begin
float8VectSub(dst, dst, op1);
continue;
end;
AVT_DOUBLE: begin
doubleVectSub(dst, dst, op1);
continue;
end;
AVT_DOUBLE2: begin
double2VectSub(dst, dst, op1);
continue;
end;
AVT_DOUBLE4: begin
double4VectSub(dst, dst, op1);
continue;
end;
AVT_DOUBLE8: begin
double8VectSub(dst, dst, op1);
continue;
end;
end;
end;
finally
op1.free();
end;
raise AVTCompilerException.create('The operator ---- is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
end;
OPER_VECT_SUBS: begin
op1 := AVTConstant.create();
try
pos := parseMultiplicative(op1, typeRef, source, pos + 1);
typeOperand0Ref := dst.valueType;
typeOperand1Ref := op1.valueType;
typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
if typeCommonRef is AVTTypePrimitive then begin
cast(dst, dst, AVTTypePrimitive(typeCommonRef));
cast(op1, op1, AVTTypePrimitive(typeCommonRef));
case AVTTypePrimitive(typeCommonRef).primitiveKind of
AVT_BYTE: begin
byteVectSubs(dst, dst, op1);
continue;
end;
AVT_BYTE2: begin
byte2VectSubs(dst, dst, op1);
continue;
end;
AVT_BYTE4: begin
byte4VectSubs(dst, dst, op1);
continue;
end;
AVT_BYTE8: begin
byte8VectSubs(dst, dst, op1);
continue;
end;
AVT_SHORT: begin
shortVectSubs(dst, dst, op1);
continue;
end;
AVT_SHORT2: begin
short2VectSubs(dst, dst, op1);
continue;
end;
AVT_SHORT4: begin
short4VectSubs(dst, dst, op1);
continue;
end;
AVT_SHORT8: begin
short8VectSubs(dst, dst, op1);
continue;
end;
end;
end;
finally
op1.free();
end;
raise AVTCompilerException.create('The operator |--| is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
end;
OPER_VECT_SUBU: begin
op1 := AVTConstant.create();
try
pos := parseMultiplicative(op1, typeRef, source, pos + 1);
typeOperand0Ref := dst.valueType;
typeOperand1Ref := op1.valueType;
typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
if typeCommonRef is AVTTypePrimitive then begin
cast(dst, dst, AVTTypePrimitive(typeCommonRef));
cast(op1, op1, AVTTypePrimitive(typeCommonRef));
case AVTTypePrimitive(typeCommonRef).primitiveKind of
AVT_BYTE: begin
byteVectSubu(dst, dst, op1);
continue;
end;
AVT_BYTE2: begin
byte2VectSubu(dst, dst, op1);
continue;
end;
AVT_BYTE4: begin
byte4VectSubu(dst, dst, op1);
continue;
end;
AVT_BYTE8: begin
byte8VectSubu(dst, dst, op1);
continue;
end;
AVT_SHORT: begin
shortVectSubu(dst, dst, op1);
continue;
end;
AVT_SHORT2: begin
short2VectSubu(dst, dst, op1);
continue;
end;
AVT_SHORT4: begin
short4VectSubu(dst, dst, op1);
continue;
end;
AVT_SHORT8: begin
short8VectSubu(dst, dst, op1);
continue;
end;
end;
end;
finally
op1.free();
end;
raise AVTCompilerException.create('The operator #--# is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
end
else
break;
end;
until false;
result := pos;
end;
function AVTConstantExpression.parseShift(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
var
primitiveKind: int;
operatorPos: int;
op1: AVTConstant;
typeOperand0Ref: AVTType;
typeOperand1Ref: AVTType;
begin
pos := parseAdditive(dst, typeRef, source, pos);
repeat
operatorPos := pos;
case source.getLexemeType(pos) of
OPER_SCAL_SAR: begin
op1 := AVTConstant.create();
try
pos := parseAdditive(op1, typeRef, source, pos + 1);
typeOperand0Ref := dst.valueType;
typeOperand1Ref := op1.valueType;
if typeOperand1Ref is AVTTypePrimitive then begin
primitiveKind := AVTTypePrimitive(typeOperand1Ref).primitiveKind;
end else begin
primitiveKind := 0;
end;
if ((primitiveKind = AVT_BYTE) or (primitiveKind = AVT_SHORT) or (primitiveKind = AVT_INT)) and (typeOperand0Ref is AVTTypePrimitive) then begin
case AVTTypePrimitive(typeOperand0Ref).primitiveKind of
AVT_CHAR: begin
dst.value.asInt := int(dst.value.asChar);
intScalSar(dst, dst, op1);
continue;
end;
AVT_BYTE: begin
byteScalSar(dst, dst, op1);
continue;
end;
AVT_BYTE2: begin
byte2ScalSar(dst, dst, op1);
continue;
end;
AVT_BYTE4: begin
byte4ScalSar(dst, dst, op1);
continue;
end;
AVT_BYTE8: begin
byte8ScalSar(dst, dst, op1);
continue;
end;
AVT_SHORT: begin
shortScalSar(dst, dst, op1);
continue;
end;
AVT_SHORT2: begin
short2ScalSar(dst, dst, op1);
continue;
end;
AVT_SHORT4: begin
short4ScalSar(dst, dst, op1);
continue;
end;
AVT_SHORT8: begin
short8ScalSar(dst, dst, op1);
continue;
end;
AVT_INT: begin
intScalSar(dst, dst, op1);
continue;
end;
AVT_INT2: begin
int2ScalSar(dst, dst, op1);
continue;
end;
AVT_INT4: begin
int4ScalSar(dst, dst, op1);
continue;
end;
AVT_INT8: begin
int8ScalSar(dst, dst, op1);
continue;
end;
AVT_LONG: begin
longScalSar(dst, dst, op1);
continue;
end;
AVT_LONG2: begin
long2ScalSar(dst, dst, op1);
continue;
end;
AVT_LONG4: begin
long4ScalSar(dst, dst, op1);
continue;
end;
AVT_LONG8: begin
long8ScalSar(dst, dst, op1);
continue;
end;
end;
end;
finally
op1.free();
end;
raise AVTCompilerException.create('The operator >> is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
end;
OPER_SCAL_SAL: begin
op1 := AVTConstant.create();
try
pos := parseAdditive(op1, typeRef, source, pos + 1);
typeOperand0Ref := dst.valueType;
typeOperand1Ref := op1.valueType;
if typeOperand1Ref is AVTTypePrimitive then begin
primitiveKind := AVTTypePrimitive(typeOperand1Ref).primitiveKind;
end else begin
primitiveKind := 0;
end;
if ((primitiveKind = AVT_BYTE) or (primitiveKind = AVT_SHORT) or (primitiveKind = AVT_INT)) and (typeOperand0Ref is AVTTypePrimitive) then begin
case AVTTypePrimitive(typeOperand0Ref).primitiveKind of
AVT_CHAR: begin
dst.value.asInt := int(dst.value.asChar);
intScalSal(dst, dst, op1);
continue;
end;
AVT_BYTE: begin
byteScalSal(dst, dst, op1);
continue;
end;
AVT_BYTE2: begin
byte2ScalSal(dst, dst, op1);
continue;
end;
AVT_BYTE4: begin
byte4ScalSal(dst, dst, op1);
continue;
end;
AVT_BYTE8: begin
byte8ScalSal(dst, dst, op1);
continue;
end;
AVT_SHORT: begin
shortScalSal(dst, dst, op1);
continue;
end;
AVT_SHORT2: begin
short2ScalSal(dst, dst, op1);
continue;
end;
AVT_SHORT4: begin
short4ScalSal(dst, dst, op1);
continue;
end;
AVT_SHORT8: begin
short8ScalSal(dst, dst, op1);
continue;
end;
AVT_INT: begin
intScalSal(dst, dst, op1);
continue;
end;
AVT_INT2: begin
int2ScalSal(dst, dst, op1);
continue;
end;
AVT_INT4: begin
int4ScalSal(dst, dst, op1);
continue;
end;
AVT_INT8: begin
int8ScalSal(dst, dst, op1);
continue;
end;
AVT_LONG: begin
longScalSal(dst, dst, op1);
continue;
end;
AVT_LONG2: begin
long2ScalSal(dst, dst, op1);
continue;
end;
AVT_LONG4: begin
long4ScalSal(dst, dst, op1);
continue;
end;
AVT_LONG8: begin
long8ScalSal(dst, dst, op1);
continue;
end;
end;
end;
finally
op1.free();
end;
raise AVTCompilerException.create('The operator << is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
end;
OPER_SCAL_SHR: begin
op1 := AVTConstant.create();
try
pos := parseAdditive(op1, typeRef, source, pos + 1);
typeOperand0Ref := dst.valueType;
typeOperand1Ref := op1.valueType;
if typeOperand1Ref is AVTTypePrimitive then begin
primitiveKind := AVTTypePrimitive(typeOperand1Ref).primitiveKind;
end else begin
primitiveKind := 0;
end;
if ((primitiveKind = AVT_BYTE) or (primitiveKind = AVT_SHORT) or (primitiveKind = AVT_INT)) and (typeOperand0Ref is AVTTypePrimitive) then begin
case AVTTypePrimitive(typeOperand0Ref).primitiveKind of
AVT_CHAR: begin
dst.value.asInt := int(dst.value.asChar);
intScalShr(dst, dst, op1);
continue;
end;
AVT_BYTE: begin
byteScalShr(dst, dst, op1);
continue;
end;
AVT_BYTE2: begin
byte2ScalShr(dst, dst, op1);
continue;
end;
AVT_BYTE4: begin
byte4ScalShr(dst, dst, op1);
continue;
end;
AVT_BYTE8: begin
byte8ScalShr(dst, dst, op1);
continue;
end;
AVT_SHORT: begin
shortScalShr(dst, dst, op1);
continue;
end;
AVT_SHORT2: begin
short2ScalShr(dst, dst, op1);
continue;
end;
AVT_SHORT4: begin
short4ScalShr(dst, dst, op1);
continue;
end;
AVT_SHORT8: begin
short8ScalShr(dst, dst, op1);
continue;
end;
AVT_INT: begin
intScalShr(dst, dst, op1);
continue;
end;
AVT_INT2: begin
int2ScalShr(dst, dst, op1);
continue;
end;
AVT_INT4: begin
int4ScalShr(dst, dst, op1);
continue;
end;
AVT_INT8: begin
int8ScalShr(dst, dst, op1);
continue;
end;
AVT_LONG: begin
longScalShr(dst, dst, op1);
continue;
end;
AVT_LONG2: begin
long2ScalShr(dst, dst, op1);
continue;
end;
AVT_LONG4: begin
long4ScalShr(dst, dst, op1);
continue;
end;
AVT_LONG8: begin
long8ScalShr(dst, dst, op1);
continue;
end;
end;
end;
finally
op1.free();
end;
raise AVTCompilerException.create('The operator >>> is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
end;
OPER_VECT_SAR: begin
op1 := AVTConstant.create();
try
pos := parseAdditive(op1, typeRef, source, pos + 1);
typeOperand0Ref := dst.valueType;
typeOperand1Ref := op1.valueType;
if typeOperand1Ref is AVTTypePrimitive then begin
primitiveKind := AVTTypePrimitive(typeOperand1Ref).primitiveKind;
end else begin
primitiveKind := 0;
end;
if ((primitiveKind = AVT_BYTE) or (primitiveKind = AVT_SHORT) or (primitiveKind = AVT_INT)) and (typeOperand0Ref is AVTTypePrimitive) then begin
case AVTTypePrimitive(typeOperand0Ref).primitiveKind of
AVT_CHAR: begin
dst.value.asInt := int(dst.value.asChar);
intVectSar(dst, dst, op1);
continue;
end;
AVT_BYTE: begin
byteVectSar(dst, dst, op1);
continue;
end;
AVT_BYTE2: begin
byte2VectSar(dst, dst, op1);
continue;
end;
AVT_BYTE4: begin
byte4VectSar(dst, dst, op1);
continue;
end;
AVT_BYTE8: begin
byte8VectSar(dst, dst, op1);
continue;
end;
AVT_SHORT: begin
shortVectSar(dst, dst, op1);
continue;
end;
AVT_SHORT2: begin
short2VectSar(dst, dst, op1);
continue;
end;
AVT_SHORT4: begin
short4VectSar(dst, dst, op1);
continue;
end;
AVT_SHORT8: begin
short8VectSar(dst, dst, op1);
continue;
end;
AVT_INT: begin
intVectSar(dst, dst, op1);
continue;
end;
AVT_INT2: begin
int2VectSar(dst, dst, op1);
continue;
end;
AVT_INT4: begin
int4VectSar(dst, dst, op1);
continue;
end;
AVT_INT8: begin
int8VectSar(dst, dst, op1);
continue;
end;
AVT_LONG: begin
longVectSar(dst, dst, op1);
continue;
end;
AVT_LONG2: begin
long2VectSar(dst, dst, op1);
continue;
end;
AVT_LONG4: begin
long4VectSar(dst, dst, op1);
continue;
end;
AVT_LONG8: begin
long8VectSar(dst, dst, op1);
continue;
end;
end;
end;
finally
op1.free();
end;
raise AVTCompilerException.create('The operator >>>> is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
end;
OPER_VECT_SAL: begin
op1 := AVTConstant.create();
try
pos := parseAdditive(op1, typeRef, source, pos + 1);
typeOperand0Ref := dst.valueType;
typeOperand1Ref := op1.valueType;
if typeOperand1Ref is AVTTypePrimitive then begin
primitiveKind := AVTTypePrimitive(typeOperand1Ref).primitiveKind;
end else begin
primitiveKind := 0;
end;
if ((primitiveKind = AVT_BYTE) or (primitiveKind = AVT_SHORT) or (primitiveKind = AVT_INT)) and (typeOperand0Ref is AVTTypePrimitive) then begin
case AVTTypePrimitive(typeOperand0Ref).primitiveKind of
AVT_CHAR: begin
dst.value.asInt := int(dst.value.asChar);
intVectSal(dst, dst, op1);
continue;
end;
AVT_BYTE: begin
byteVectSal(dst, dst, op1);
continue;
end;
AVT_BYTE2: begin
byte2VectSal(dst, dst, op1);
continue;
end;
AVT_BYTE4: begin
byte4VectSal(dst, dst, op1);
continue;
end;
AVT_BYTE8: begin
byte8VectSal(dst, dst, op1);
continue;
end;
AVT_SHORT: begin
shortVectSal(dst, dst, op1);
continue;
end;
AVT_SHORT2: begin
short2VectSal(dst, dst, op1);
continue;
end;
AVT_SHORT4: begin
short4VectSal(dst, dst, op1);
continue;
end;
AVT_SHORT8: begin
short8VectSal(dst, dst, op1);
continue;
end;
AVT_INT: begin
intVectSal(dst, dst, op1);
continue;
end;
AVT_INT2: begin
int2VectSal(dst, dst, op1);
continue;
end;
AVT_INT4: begin
int4VectSal(dst, dst, op1);
continue;
end;
AVT_INT8: begin
int8VectSal(dst, dst, op1);
continue;
end;
AVT_LONG: begin
longVectSal(dst, dst, op1);
continue;
end;
AVT_LONG2: begin
long2VectSal(dst, dst, op1);
continue;
end;
AVT_LONG4: begin
long4VectSal(dst, dst, op1);
continue;
end;
AVT_LONG8: begin
long8VectSal(dst, dst, op1);
continue;
end;
end;
end;
finally
op1.free();
end;
raise AVTCompilerException.create('The operator <<<< is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
end;
OPER_VECT_SHR: begin
op1 := AVTConstant.create();
try
pos := parseAdditive(op1, typeRef, source, pos + 1);
typeOperand0Ref := dst.valueType;
typeOperand1Ref := op1.valueType;
if typeOperand1Ref is AVTTypePrimitive then begin
primitiveKind := AVTTypePrimitive(typeOperand1Ref).primitiveKind;
end else begin
primitiveKind := 0;
end;
if ((primitiveKind = AVT_BYTE) or (primitiveKind = AVT_SHORT) or (primitiveKind = AVT_INT)) and (typeOperand0Ref is AVTTypePrimitive) then begin
case AVTTypePrimitive(typeOperand0Ref).primitiveKind of
AVT_CHAR: begin
dst.value.asInt := int(dst.value.asChar);
intVectShr(dst, dst, op1);
continue;
end;
AVT_BYTE: begin
byteVectShr(dst, dst, op1);
continue;
end;
AVT_BYTE2: begin
byte2VectShr(dst, dst, op1);
continue;
end;
AVT_BYTE4: begin
byte4VectShr(dst, dst, op1);
continue;
end;
AVT_BYTE8: begin
byte8VectShr(dst, dst, op1);
continue;
end;
AVT_SHORT: begin
shortVectShr(dst, dst, op1);
continue;
end;
AVT_SHORT2: begin
short2VectShr(dst, dst, op1);
continue;
end;
AVT_SHORT4: begin
short4VectShr(dst, dst, op1);
continue;
end;
AVT_SHORT8: begin
short8VectShr(dst, dst, op1);
continue;
end;
AVT_INT: begin
intVectShr(dst, dst, op1);
continue;
end;
AVT_INT2: begin
int2VectShr(dst, dst, op1);
continue;
end;
AVT_INT4: begin
int4VectShr(dst, dst, op1);
continue;
end;
AVT_INT8: begin
int8VectShr(dst, dst, op1);
continue;
end;
AVT_LONG: begin
longVectShr(dst, dst, op1);
continue;
end;
AVT_LONG2: begin
long2VectShr(dst, dst, op1);
continue;
end;
AVT_LONG4: begin
long4VectShr(dst, dst, op1);
continue;
end;
AVT_LONG8: begin
long8VectShr(dst, dst, op1);
continue;
end;
end;
end;
finally
op1.free();
end;
raise AVTCompilerException.create('The operator >>>>> is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
end
else
break;
end;
until false;
result := pos;
end;
function AVTConstantExpression.parseRelational(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
var
operatorPos: int;
op1: AVTConstant;
typeCommonRef: AVTType;
typeOperand0Ref: AVTType;
typeOperand1Ref: AVTType;
begin
pos := parseShift(dst, typeRef, source, pos);
repeat
operatorPos := pos;
case source.getLexemeType(pos) of
OPER_SCAL_G: begin
op1 := AVTConstant.create();
try
pos := parseShift(op1, typeRef, source, pos + 1);
typeOperand0Ref := dst.valueType;
typeOperand1Ref := op1.valueType;
typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
if typeCommonRef is AVTTypePrimitive then begin
cast(dst, dst, AVTTypePrimitive(typeCommonRef));
cast(op1, op1, AVTTypePrimitive(typeCommonRef));
case AVTTypePrimitive(typeCommonRef).primitiveKind of
AVT_BYTE: begin
byteScalG(dst, dst, op1);
continue;
end;
AVT_SHORT: begin
shortScalG(dst, dst, op1);
continue;
end;
AVT_INT: begin
intScalG(dst, dst, op1);
continue;
end;
AVT_LONG: begin
longScalG(dst, dst, op1);
continue;
end;
AVT_FLOAT: begin
floatScalG(dst, dst, op1);
continue;
end;
AVT_DOUBLE: begin
doubleScalG(dst, dst, op1);
continue;
end;
AVT_REAL: begin
realScalG(dst, dst, op1);
continue;
end;
end;
end;
finally
op1.free();
end;
raise AVTCompilerException.create('The operator > is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
end;
OPER_SCAL_GE: begin
op1 := AVTConstant.create();
try
pos := parseShift(op1, typeRef, source, pos + 1);
typeOperand0Ref := dst.valueType;
typeOperand1Ref := op1.valueType;
typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
if typeCommonRef is AVTTypePrimitive then begin
cast(dst, dst, AVTTypePrimitive(typeCommonRef));
cast(op1, op1, AVTTypePrimitive(typeCommonRef));
case AVTTypePrimitive(typeCommonRef).primitiveKind of
AVT_BYTE: begin
byteScalGE(dst, dst, op1);
continue;
end;
AVT_SHORT: begin
shortScalGE(dst, dst, op1);
continue;
end;
AVT_INT: begin
intScalGE(dst, dst, op1);
continue;
end;
AVT_LONG: begin
longScalGE(dst, dst, op1);
continue;
end;
AVT_FLOAT: begin
floatScalGE(dst, dst, op1);
continue;
end;
AVT_DOUBLE: begin
doubleScalGE(dst, dst, op1);
continue;
end;
AVT_REAL: begin
realScalGE(dst, dst, op1);
continue;
end;
end;
end;
finally
op1.free();
end;
raise AVTCompilerException.create('The operator >= is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
end;
OPER_SCAL_L: begin
op1 := AVTConstant.create();
try
pos := parseShift(op1, typeRef, source, pos + 1);
typeOperand0Ref := dst.valueType;
typeOperand1Ref := op1.valueType;
typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
if typeCommonRef is AVTTypePrimitive then begin
cast(dst, dst, AVTTypePrimitive(typeCommonRef));
cast(op1, op1, AVTTypePrimitive(typeCommonRef));
case AVTTypePrimitive(typeCommonRef).primitiveKind of
AVT_BYTE: begin
byteScalL(dst, dst, op1);
continue;
end;
AVT_SHORT: begin
shortScalL(dst, dst, op1);
continue;
end;
AVT_INT: begin
intScalL(dst, dst, op1);
continue;
end;
AVT_LONG: begin
longScalL(dst, dst, op1);
continue;
end;
AVT_FLOAT: begin
floatScalL(dst, dst, op1);
continue;
end;
AVT_DOUBLE: begin
doubleScalL(dst, dst, op1);
continue;
end;
AVT_REAL: begin
realScalL(dst, dst, op1);
continue;
end;
end;
end;
finally
op1.free();
end;
raise AVTCompilerException.create('The operator < is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
end;
OPER_SCAL_LE: begin
op1 := AVTConstant.create();
try
pos := parseShift(op1, typeRef, source, pos + 1);
typeOperand0Ref := dst.valueType;
typeOperand1Ref := op1.valueType;
typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
if typeCommonRef is AVTTypePrimitive then begin
cast(dst, dst, AVTTypePrimitive(typeCommonRef));
cast(op1, op1, AVTTypePrimitive(typeCommonRef));
case AVTTypePrimitive(typeCommonRef).primitiveKind of
AVT_BYTE: begin
byteScalLE(dst, dst, op1);
continue;
end;
AVT_SHORT: begin
shortScalLE(dst, dst, op1);
continue;
end;
AVT_INT: begin
intScalLE(dst, dst, op1);
continue;
end;
AVT_LONG: begin
longScalLE(dst, dst, op1);
continue;
end;
AVT_FLOAT: begin
floatScalLE(dst, dst, op1);
continue;
end;
AVT_DOUBLE: begin
doubleScalLE(dst, dst, op1);
continue;
end;
AVT_REAL: begin
realScalLE(dst, dst, op1);
continue;
end;
end;
end;
finally
op1.free();
end;
raise AVTCompilerException.create('The operator <= is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
end;
OPER_VECT_G: begin
op1 := AVTConstant.create();
try
pos := parseShift(op1, typeRef, source, pos + 1);
typeOperand0Ref := dst.valueType;
typeOperand1Ref := op1.valueType;
typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
if typeCommonRef is AVTTypePrimitive then begin
cast(dst, dst, AVTTypePrimitive(typeCommonRef));
cast(op1, op1, AVTTypePrimitive(typeCommonRef));
case AVTTypePrimitive(typeCommonRef).primitiveKind of
AVT_BYTE: begin
byteVectG(dst, dst, op1);
continue;
end;
AVT_BYTE2: begin
byte2VectG(dst, dst, op1);
continue;
end;
AVT_BYTE4: begin
byte4VectG(dst, dst, op1);
continue;
end;
AVT_BYTE8: begin
byte8VectG(dst, dst, op1);
continue;
end;
AVT_SHORT: begin
shortVectG(dst, dst, op1);
continue;
end;
AVT_SHORT2: begin
short2VectG(dst, dst, op1);
continue;
end;
AVT_SHORT4: begin
short4VectG(dst, dst, op1);
continue;
end;
AVT_SHORT8: begin
short8VectG(dst, dst, op1);
continue;
end;
AVT_INT: begin
intVectG(dst, dst, op1);
continue;
end;
AVT_INT2: begin
int2VectG(dst, dst, op1);
continue;
end;
AVT_INT4: begin
int4VectG(dst, dst, op1);
continue;
end;
AVT_INT8: begin
int8VectG(dst, dst, op1);
continue;
end;
AVT_LONG: begin
longVectG(dst, dst, op1);
continue;
end;
AVT_LONG2: begin
long2VectG(dst, dst, op1);
continue;
end;
AVT_LONG4: begin
long4VectG(dst, dst, op1);
continue;
end;
AVT_LONG8: begin
long8VectG(dst, dst, op1);
continue;
end;
AVT_FLOAT: begin
floatVectG(dst, dst, op1);
continue;
end;
AVT_FLOAT2: begin
float2VectG(dst, dst, op1);
continue;
end;
AVT_FLOAT4: begin
float4VectG(dst, dst, op1);
continue;
end;
AVT_FLOAT8: begin
float8VectG(dst, dst, op1);
continue;
end;
AVT_DOUBLE: begin
doubleVectG(dst, dst, op1);
continue;
end;
AVT_DOUBLE2: begin
double2VectG(dst, dst, op1);
continue;
end;
AVT_DOUBLE4: begin
double4VectG(dst, dst, op1);
continue;
end;
AVT_DOUBLE8: begin
double8VectG(dst, dst, op1);
continue;
end;
end;
end;
finally
op1.free();
end;
raise AVTCompilerException.create('The operator |>>| is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
end;
OPER_VECT_GE: begin
op1 := AVTConstant.create();
try
pos := parseShift(op1, typeRef, source, pos + 1);
typeOperand0Ref := dst.valueType;
typeOperand1Ref := op1.valueType;
typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
if typeCommonRef is AVTTypePrimitive then begin
cast(dst, dst, AVTTypePrimitive(typeCommonRef));
cast(op1, op1, AVTTypePrimitive(typeCommonRef));
case AVTTypePrimitive(typeCommonRef).primitiveKind of
AVT_BYTE: begin
byteVectGE(dst, dst, op1);
continue;
end;
AVT_BYTE2: begin
byte2VectGE(dst, dst, op1);
continue;
end;
AVT_BYTE4: begin
byte4VectGE(dst, dst, op1);
continue;
end;
AVT_BYTE8: begin
byte8VectGE(dst, dst, op1);
continue;
end;
AVT_SHORT: begin
shortVectGE(dst, dst, op1);
continue;
end;
AVT_SHORT2: begin
short2VectGE(dst, dst, op1);
continue;
end;
AVT_SHORT4: begin
short4VectGE(dst, dst, op1);
continue;
end;
AVT_SHORT8: begin
short8VectGE(dst, dst, op1);
continue;
end;
AVT_INT: begin
intVectGE(dst, dst, op1);
continue;
end;
AVT_INT2: begin
int2VectGE(dst, dst, op1);
continue;
end;
AVT_INT4: begin
int4VectGE(dst, dst, op1);
continue;
end;
AVT_INT8: begin
int8VectGE(dst, dst, op1);
continue;
end;
AVT_LONG: begin
longVectGE(dst, dst, op1);
continue;
end;
AVT_LONG2: begin
long2VectGE(dst, dst, op1);
continue;
end;
AVT_LONG4: begin
long4VectGE(dst, dst, op1);
continue;
end;
AVT_LONG8: begin
long8VectGE(dst, dst, op1);
continue;
end;
AVT_FLOAT: begin
floatVectGE(dst, dst, op1);
continue;
end;
AVT_FLOAT2: begin
float2VectGE(dst, dst, op1);
continue;
end;
AVT_FLOAT4: begin
float4VectGE(dst, dst, op1);
continue;
end;
AVT_FLOAT8: begin
float8VectGE(dst, dst, op1);
continue;
end;
AVT_DOUBLE: begin
doubleVectGE(dst, dst, op1);
continue;
end;
AVT_DOUBLE2: begin
double2VectGE(dst, dst, op1);
continue;
end;
AVT_DOUBLE4: begin
double4VectGE(dst, dst, op1);
continue;
end;
AVT_DOUBLE8: begin
double8VectGE(dst, dst, op1);
continue;
end;
end;
end;
finally
op1.free();
end;
raise AVTCompilerException.create('The operator |>=| is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
end;
OPER_VECT_L: begin
op1 := AVTConstant.create();
try
pos := parseShift(op1, typeRef, source, pos + 1);
typeOperand0Ref := dst.valueType;
typeOperand1Ref := op1.valueType;
typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
if typeCommonRef is AVTTypePrimitive then begin
cast(dst, dst, AVTTypePrimitive(typeCommonRef));
cast(op1, op1, AVTTypePrimitive(typeCommonRef));
case AVTTypePrimitive(typeCommonRef).primitiveKind of
AVT_BYTE: begin
byteVectL(dst, dst, op1);
continue;
end;
AVT_BYTE2: begin
byte2VectL(dst, dst, op1);
continue;
end;
AVT_BYTE4: begin
byte4VectL(dst, dst, op1);
continue;
end;
AVT_BYTE8: begin
byte8VectL(dst, dst, op1);
continue;
end;
AVT_SHORT: begin
shortVectL(dst, dst, op1);
continue;
end;
AVT_SHORT2: begin
short2VectL(dst, dst, op1);
continue;
end;
AVT_SHORT4: begin
short4VectL(dst, dst, op1);
continue;
end;
AVT_SHORT8: begin
short8VectL(dst, dst, op1);
continue;
end;
AVT_INT: begin
intVectL(dst, dst, op1);
continue;
end;
AVT_INT2: begin
int2VectL(dst, dst, op1);
continue;
end;
AVT_INT4: begin
int4VectL(dst, dst, op1);
continue;
end;
AVT_INT8: begin
int8VectL(dst, dst, op1);
continue;
end;
AVT_LONG: begin
longVectL(dst, dst, op1);
continue;
end;
AVT_LONG2: begin
long2VectL(dst, dst, op1);
continue;
end;
AVT_LONG4: begin
long4VectL(dst, dst, op1);
continue;
end;
AVT_LONG8: begin
long8VectL(dst, dst, op1);
continue;
end;
AVT_FLOAT: begin
floatVectL(dst, dst, op1);
continue;
end;
AVT_FLOAT2: begin
float2VectL(dst, dst, op1);
continue;
end;
AVT_FLOAT4: begin
float4VectL(dst, dst, op1);
continue;
end;
AVT_FLOAT8: begin
float8VectL(dst, dst, op1);
continue;
end;
AVT_DOUBLE: begin
doubleVectL(dst, dst, op1);
continue;
end;
AVT_DOUBLE2: begin
double2VectL(dst, dst, op1);
continue;
end;
AVT_DOUBLE4: begin
double4VectL(dst, dst, op1);
continue;
end;
AVT_DOUBLE8: begin
double8VectL(dst, dst, op1);
continue;
end;
end;
end;
finally
op1.free();
end;
raise AVTCompilerException.create('The operator |<<| is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
end;
OPER_VECT_LE: begin
op1 := AVTConstant.create();
try
pos := parseShift(op1, typeRef, source, pos + 1);
typeOperand0Ref := dst.valueType;
typeOperand1Ref := op1.valueType;
typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
if typeCommonRef is AVTTypePrimitive then begin
cast(dst, dst, AVTTypePrimitive(typeCommonRef));
cast(op1, op1, AVTTypePrimitive(typeCommonRef));
case AVTTypePrimitive(typeCommonRef).primitiveKind of
AVT_BYTE: begin
byteVectLE(dst, dst, op1);
continue;
end;
AVT_BYTE2: begin
byte2VectLE(dst, dst, op1);
continue;
end;
AVT_BYTE4: begin
byte4VectLE(dst, dst, op1);
continue;
end;
AVT_BYTE8: begin
byte8VectLE(dst, dst, op1);
continue;
end;
AVT_SHORT: begin
shortVectLE(dst, dst, op1);
continue;
end;
AVT_SHORT2: begin
short2VectLE(dst, dst, op1);
continue;
end;
AVT_SHORT4: begin
short4VectLE(dst, dst, op1);
continue;
end;
AVT_SHORT8: begin
short8VectLE(dst, dst, op1);
continue;
end;
AVT_INT: begin
intVectLE(dst, dst, op1);
continue;
end;
AVT_INT2: begin
int2VectLE(dst, dst, op1);
continue;
end;
AVT_INT4: begin
int4VectLE(dst, dst, op1);
continue;
end;
AVT_INT8: begin
int8VectLE(dst, dst, op1);
continue;
end;
AVT_LONG: begin
longVectLE(dst, dst, op1);
continue;
end;
AVT_LONG2: begin
long2VectLE(dst, dst, op1);
continue;
end;
AVT_LONG4: begin
long4VectLE(dst, dst, op1);
continue;
end;
AVT_LONG8: begin
long8VectLE(dst, dst, op1);
continue;
end;
AVT_FLOAT: begin
floatVectLE(dst, dst, op1);
continue;
end;
AVT_FLOAT2: begin
float2VectLE(dst, dst, op1);
continue;
end;
AVT_FLOAT4: begin
float4VectLE(dst, dst, op1);
continue;
end;
AVT_FLOAT8: begin
float8VectLE(dst, dst, op1);
continue;
end;
AVT_DOUBLE: begin
doubleVectLE(dst, dst, op1);
continue;
end;
AVT_DOUBLE2: begin
double2VectLE(dst, dst, op1);
continue;
end;
AVT_DOUBLE4: begin
double4VectLE(dst, dst, op1);
continue;
end;
AVT_DOUBLE8: begin
double8VectLE(dst, dst, op1);
continue;
end;
end;
end;
finally
op1.free();
end;
raise AVTCompilerException.create('The operator |<=| is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
end
else
break;
end;
until false;
result := pos;
end;
function AVTConstantExpression.parseEquality(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
var
operatorPos: int;
op1: AVTConstant;
typeCommonRef: AVTType;
typeOperand0Ref: AVTType;
typeOperand1Ref: AVTType;
begin
pos := parseRelational(dst, typeRef, source, pos);
repeat
operatorPos := pos;
case source.getLexemeType(pos) of
OPER_SCAL_E: begin
op1 := AVTConstant.create();
try
pos := parseRelational(op1, typeRef, source, pos + 1);
typeOperand0Ref := dst.valueType;
typeOperand1Ref := op1.valueType;
typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
if typeCommonRef = nil then begin
dst.clear();
dst.value.asBoolean := true;
dst.valueType := getPrimitiveType(AVT_BOOLEAN);
continue;
end;
if typeCommonRef is AVTTypeStructured then begin
if dst.value.isNull then begin
dst.value.asBoolean := op1.value.isNull;
end else begin
if op1.value.isNull then begin
dst.value.asBoolean := false;
end else begin
dst.value.asBoolean := dst.value.asString = op1.value.asString;
end;
dst.value.asString := '';
end;
dst.valueType := getPrimitiveType(AVT_BOOLEAN);
continue;
end;
if typeCommonRef is AVTTypePrimitive then begin
cast(dst, dst, AVTTypePrimitive(typeCommonRef));
cast(op1, op1, AVTTypePrimitive(typeCommonRef));
case AVTTypePrimitive(typeCommonRef).primitiveKind of
AVT_BOOLEAN: begin
dst.value.asBoolean := dst.value.asBoolean = op1.value.asBoolean;
dst.valueType := getPrimitiveType(AVT_BOOLEAN);
continue;
end;
AVT_BYTE: begin
byteScalE(dst, dst, op1);
continue;
end;
AVT_BYTE2: begin
byte2ScalE(dst, dst, op1);
continue;
end;
AVT_BYTE4: begin
byte4ScalE(dst, dst, op1);
continue;
end;
AVT_BYTE8: begin
byte8ScalE(dst, dst, op1);
continue;
end;
AVT_SHORT: begin
shortScalE(dst, dst, op1);
continue;
end;
AVT_SHORT2: begin
short2ScalE(dst, dst, op1);
continue;
end;
AVT_SHORT4: begin
short4ScalE(dst, dst, op1);
continue;
end;
AVT_SHORT8: begin
short8ScalE(dst, dst, op1);
continue;
end;
AVT_INT: begin
intScalE(dst, dst, op1);
continue;
end;
AVT_INT2: begin
int2ScalE(dst, dst, op1);
continue;
end;
AVT_INT4: begin
int4ScalE(dst, dst, op1);
continue;
end;
AVT_INT8: begin
int8ScalE(dst, dst, op1);
continue;
end;
AVT_LONG: begin
longScalE(dst, dst, op1);
continue;
end;
AVT_LONG2: begin
long2ScalE(dst, dst, op1);
continue;
end;
AVT_LONG4: begin
long4ScalE(dst, dst, op1);
continue;
end;
AVT_LONG8: begin
long8ScalE(dst, dst, op1);
continue;
end;
AVT_FLOAT: begin
floatScalE(dst, dst, op1);
continue;
end;
AVT_FLOAT2: begin
float2ScalE(dst, dst, op1);
continue;
end;
AVT_FLOAT4: begin
float4ScalE(dst, dst, op1);
continue;
end;
AVT_FLOAT8: begin
float8ScalE(dst, dst, op1);
continue;
end;
AVT_DOUBLE: begin
doubleScalE(dst, dst, op1);
continue;
end;
AVT_DOUBLE2: begin
double2ScalE(dst, dst, op1);
continue;
end;
AVT_DOUBLE4: begin
double4ScalE(dst, dst, op1);
continue;
end;
AVT_DOUBLE8: begin
double8ScalE(dst, dst, op1);
continue;
end;
AVT_REAL: begin
realScalE(dst, dst, op1);
continue;
end;
end;
end;
finally
op1.free();
end;
raise AVTCompilerException.create('The operator == is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
end;
OPER_SCAL_NE: begin
op1 := AVTConstant.create();
try
pos := parseRelational(op1, typeRef, source, pos + 1);
typeOperand0Ref := dst.valueType;
typeOperand1Ref := op1.valueType;
typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
if typeCommonRef = nil then begin
dst.clear();
dst.value.asBoolean := false;
dst.valueType := getPrimitiveType(AVT_BOOLEAN);
continue;
end;
if typeCommonRef is AVTTypeStructured then begin
if dst.value.isNull then begin
dst.value.asBoolean := not op1.value.isNull;
end else begin
if op1.value.isNull then begin
dst.value.asBoolean := true;
end else begin
dst.value.asBoolean := dst.value.asString <> op1.value.asString;
end;
dst.value.asString := '';
end;
dst.valueType := getPrimitiveType(AVT_BOOLEAN);
continue;
end;
if typeCommonRef is AVTTypePrimitive then begin
cast(dst, dst, AVTTypePrimitive(typeCommonRef));
cast(op1, op1, AVTTypePrimitive(typeCommonRef));
case AVTTypePrimitive(typeCommonRef).primitiveKind of
AVT_BOOLEAN: begin
dst.value.asBoolean := dst.value.asBoolean <> op1.value.asBoolean;
dst.valueType := getPrimitiveType(AVT_BOOLEAN);
continue;
end;
AVT_BYTE: begin
byteScalNE(dst, dst, op1);
continue;
end;
AVT_BYTE2: begin
byte2ScalNE(dst, dst, op1);
continue;
end;
AVT_BYTE4: begin
byte4ScalNE(dst, dst, op1);
continue;
end;
AVT_BYTE8: begin
byte8ScalNE(dst, dst, op1);
continue;
end;
AVT_SHORT: begin
shortScalNE(dst, dst, op1);
continue;
end;
AVT_SHORT2: begin
short2ScalNE(dst, dst, op1);
continue;
end;
AVT_SHORT4: begin
short4ScalNE(dst, dst, op1);
continue;
end;
AVT_SHORT8: begin
short8ScalNE(dst, dst, op1);
continue;
end;
AVT_INT: begin
intScalNE(dst, dst, op1);
continue;
end;
AVT_INT2: begin
int2ScalNE(dst, dst, op1);
continue;
end;
AVT_INT4: begin
int4ScalNE(dst, dst, op1);
continue;
end;
AVT_INT8: begin
int8ScalNE(dst, dst, op1);
continue;
end;
AVT_LONG: begin
longScalNE(dst, dst, op1);
continue;
end;
AVT_LONG2: begin
long2ScalNE(dst, dst, op1);
continue;
end;
AVT_LONG4: begin
long4ScalNE(dst, dst, op1);
continue;
end;
AVT_LONG8: begin
long8ScalNE(dst, dst, op1);
continue;
end;
AVT_FLOAT: begin
floatScalNE(dst, dst, op1);
continue;
end;
AVT_FLOAT2: begin
float2ScalNE(dst, dst, op1);
continue;
end;
AVT_FLOAT4: begin
float4ScalNE(dst, dst, op1);
continue;
end;
AVT_FLOAT8: begin
float8ScalNE(dst, dst, op1);
continue;
end;
AVT_DOUBLE: begin
doubleScalNE(dst, dst, op1);
continue;
end;
AVT_DOUBLE2: begin
double2ScalNE(dst, dst, op1);
continue;
end;
AVT_DOUBLE4: begin
double4ScalNE(dst, dst, op1);
continue;
end;
AVT_DOUBLE8: begin
double8ScalNE(dst, dst, op1);
continue;
end;
AVT_REAL: begin
realScalNE(dst, dst, op1);
continue;
end;
end;
end;
finally
op1.free();
end;
raise AVTCompilerException.create('The operator != is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
end;
OPER_VECT_E: begin
op1 := AVTConstant.create();
try
pos := parseRelational(op1, typeRef, source, pos + 1);
typeOperand0Ref := dst.valueType;
typeOperand1Ref := op1.valueType;
typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
if typeCommonRef is AVTTypePrimitive then begin
cast(dst, dst, AVTTypePrimitive(typeCommonRef));
cast(op1, op1, AVTTypePrimitive(typeCommonRef));
case AVTTypePrimitive(typeCommonRef).primitiveKind of
AVT_BYTE: begin
byteVectE(dst, dst, op1);
continue;
end;
AVT_BYTE2: begin
byte2VectE(dst, dst, op1);
continue;
end;
AVT_BYTE4: begin
byte4VectE(dst, dst, op1);
continue;
end;
AVT_BYTE8: begin
byte8VectE(dst, dst, op1);
continue;
end;
AVT_SHORT: begin
shortVectE(dst, dst, op1);
continue;
end;
AVT_SHORT2: begin
short2VectE(dst, dst, op1);
continue;
end;
AVT_SHORT4: begin
short4VectE(dst, dst, op1);
continue;
end;
AVT_SHORT8: begin
short8VectE(dst, dst, op1);
continue;
end;
AVT_INT: begin
intVectE(dst, dst, op1);
continue;
end;
AVT_INT2: begin
int2VectE(dst, dst, op1);
continue;
end;
AVT_INT4: begin
int4VectE(dst, dst, op1);
continue;
end;
AVT_INT8: begin
int8VectE(dst, dst, op1);
continue;
end;
AVT_LONG: begin
longVectE(dst, dst, op1);
continue;
end;
AVT_LONG2: begin
long2VectE(dst, dst, op1);
continue;
end;
AVT_LONG4: begin
long4VectE(dst, dst, op1);
continue;
end;
AVT_LONG8: begin
long8VectE(dst, dst, op1);
continue;
end;
AVT_FLOAT: begin
floatVectE(dst, dst, op1);
continue;
end;
AVT_FLOAT2: begin
float2VectE(dst, dst, op1);
continue;
end;
AVT_FLOAT4: begin
float4VectE(dst, dst, op1);
continue;
end;
AVT_FLOAT8: begin
float8VectE(dst, dst, op1);
continue;
end;
AVT_DOUBLE: begin
doubleVectE(dst, dst, op1);
continue;
end;
AVT_DOUBLE2: begin
double2VectE(dst, dst, op1);
continue;
end;
AVT_DOUBLE4: begin
double4VectE(dst, dst, op1);
continue;
end;
AVT_DOUBLE8: begin
double8VectE(dst, dst, op1);
continue;
end;
end;
end;
finally
op1.free();
end;
raise AVTCompilerException.create('The operator |==| is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
end;
OPER_VECT_NE: begin
op1 := AVTConstant.create();
try
pos := parseRelational(op1, typeRef, source, pos + 1);
typeOperand0Ref := dst.valueType;
typeOperand1Ref := op1.valueType;
typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
if typeCommonRef is AVTTypePrimitive then begin
cast(dst, dst, AVTTypePrimitive(typeCommonRef));
cast(op1, op1, AVTTypePrimitive(typeCommonRef));
case AVTTypePrimitive(typeCommonRef).primitiveKind of
AVT_BYTE: begin
byteVectNE(dst, dst, op1);
continue;
end;
AVT_BYTE2: begin
byte2VectNE(dst, dst, op1);
continue;
end;
AVT_BYTE4: begin
byte4VectNE(dst, dst, op1);
continue;
end;
AVT_BYTE8: begin
byte8VectNE(dst, dst, op1);
continue;
end;
AVT_SHORT: begin
shortVectNE(dst, dst, op1);
continue;
end;
AVT_SHORT2: begin
short2VectNE(dst, dst, op1);
continue;
end;
AVT_SHORT4: begin
short4VectNE(dst, dst, op1);
continue;
end;
AVT_SHORT8: begin
short8VectNE(dst, dst, op1);
continue;
end;
AVT_INT: begin
intVectNE(dst, dst, op1);
continue;
end;
AVT_INT2: begin
int2VectNE(dst, dst, op1);
continue;
end;
AVT_INT4: begin
int4VectNE(dst, dst, op1);
continue;
end;
AVT_INT8: begin
int8VectNE(dst, dst, op1);
continue;
end;
AVT_LONG: begin
longVectNE(dst, dst, op1);
continue;
end;
AVT_LONG2: begin
long2VectNE(dst, dst, op1);
continue;
end;
AVT_LONG4: begin
long4VectNE(dst, dst, op1);
continue;
end;
AVT_LONG8: begin
long8VectNE(dst, dst, op1);
continue;
end;
AVT_FLOAT: begin
floatVectNE(dst, dst, op1);
continue;
end;
AVT_FLOAT2: begin
float2VectNE(dst, dst, op1);
continue;
end;
AVT_FLOAT4: begin
float4VectNE(dst, dst, op1);
continue;
end;
AVT_FLOAT8: begin
float8VectNE(dst, dst, op1);
continue;
end;
AVT_DOUBLE: begin
doubleVectNE(dst, dst, op1);
continue;
end;
AVT_DOUBLE2: begin
double2VectNE(dst, dst, op1);
continue;
end;
AVT_DOUBLE4: begin
double4VectNE(dst, dst, op1);
continue;
end;
AVT_DOUBLE8: begin
double8VectNE(dst, dst, op1);
continue;
end;
end;
end;
finally
op1.free();
end;
raise AVTCompilerException.create('The operator |!=| is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
end
else
break;
end;
until false;
result := pos;
end;
function AVTConstantExpression.parseBitAnd(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
var
operatorPos: int;
op1: AVTConstant;
typeCommonRef: AVTType;
typeOperand0Ref: AVTType;
typeOperand1Ref: AVTType;
begin
pos := parseEquality(dst, typeRef, source, pos);
while source.getLexemeType(pos) = OPER_BIT_AND do begin
operatorPos := pos;
op1 := AVTConstant.create();
try
pos := parseEquality(op1, typeRef, source, pos + 1);
typeOperand0Ref := dst.valueType;
typeOperand1Ref := op1.valueType;
typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
if typeCommonRef is AVTTypePrimitive then begin
cast(dst, dst, AVTTypePrimitive(typeCommonRef));
cast(op1, op1, AVTTypePrimitive(typeCommonRef));
case AVTTypePrimitive(typeCommonRef).primitiveKind of
AVT_BOOLEAN: begin
dst.value.asBoolean := dst.value.asBoolean and op1.value.asBoolean;
continue;
end;
AVT_BYTE: begin
byteBitAnd(dst, dst, op1);
continue;
end;
AVT_BYTE2: begin
byte2BitAnd(dst, dst, op1);
continue;
end;
AVT_BYTE4: begin
byte4BitAnd(dst, dst, op1);
continue;
end;
AVT_BYTE8: begin
byte8BitAnd(dst, dst, op1);
continue;
end;
AVT_SHORT: begin
shortBitAnd(dst, dst, op1);
continue;
end;
AVT_SHORT2: begin
short2BitAnd(dst, dst, op1);
continue;
end;
AVT_SHORT4: begin
short4BitAnd(dst, dst, op1);
continue;
end;
AVT_SHORT8: begin
short8BitAnd(dst, dst, op1);
continue;
end;
AVT_INT: begin
intBitAnd(dst, dst, op1);
continue;
end;
AVT_INT2: begin
int2BitAnd(dst, dst, op1);
continue;
end;
AVT_INT4: begin
int4BitAnd(dst, dst, op1);
continue;
end;
AVT_INT8: begin
int8BitAnd(dst, dst, op1);
continue;
end;
AVT_LONG: begin
longBitAnd(dst, dst, op1);
continue;
end;
AVT_LONG2: begin
long2BitAnd(dst, dst, op1);
continue;
end;
AVT_LONG4: begin
long4BitAnd(dst, dst, op1);
continue;
end;
AVT_LONG8: begin
long8BitAnd(dst, dst, op1);
continue;
end;
end;
end;
finally
op1.free();
end;
raise AVTCompilerException.create('The operator & is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
end;
result := pos;
end;
function AVTConstantExpression.parseBitXor(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
var
operatorPos: int;
op1: AVTConstant;
typeCommonRef: AVTType;
typeOperand0Ref: AVTType;
typeOperand1Ref: AVTType;
begin
pos := parseBitAnd(dst, typeRef, source, pos);
while source.getLexemeType(pos) = OPER_BIT_XOR do begin
operatorPos := pos;
op1 := AVTConstant.create();
try
pos := parseBitAnd(op1, typeRef, source, pos + 1);
typeOperand0Ref := dst.valueType;
typeOperand1Ref := op1.valueType;
typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
if typeCommonRef is AVTTypePrimitive then begin
cast(dst, dst, AVTTypePrimitive(typeCommonRef));
cast(op1, op1, AVTTypePrimitive(typeCommonRef));
case AVTTypePrimitive(typeCommonRef).primitiveKind of
AVT_BOOLEAN: begin
dst.value.asBoolean := dst.value.asBoolean xor op1.value.asBoolean;
continue;
end;
AVT_BYTE: begin
byteBitXor(dst, dst, op1);
continue;
end;
AVT_BYTE2: begin
byte2BitXor(dst, dst, op1);
continue;
end;
AVT_BYTE4: begin
byte4BitXor(dst, dst, op1);
continue;
end;
AVT_BYTE8: begin
byte8BitXor(dst, dst, op1);
continue;
end;
AVT_SHORT: begin
shortBitXor(dst, dst, op1);
continue;
end;
AVT_SHORT2: begin
short2BitXor(dst, dst, op1);
continue;
end;
AVT_SHORT4: begin
short4BitXor(dst, dst, op1);
continue;
end;
AVT_SHORT8: begin
short8BitXor(dst, dst, op1);
continue;
end;
AVT_INT: begin
intBitXor(dst, dst, op1);
continue;
end;
AVT_INT2: begin
int2BitXor(dst, dst, op1);
continue;
end;
AVT_INT4: begin
int4BitXor(dst, dst, op1);
continue;
end;
AVT_INT8: begin
int8BitXor(dst, dst, op1);
continue;
end;
AVT_LONG: begin
longBitXor(dst, dst, op1);
continue;
end;
AVT_LONG2: begin
long2BitXor(dst, dst, op1);
continue;
end;
AVT_LONG4: begin
long4BitXor(dst, dst, op1);
continue;
end;
AVT_LONG8: begin
long8BitXor(dst, dst, op1);
continue;
end;
end;
end;
finally
op1.free();
end;
raise AVTCompilerException.create('The operator ^ is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
end;
result := pos;
end;
function AVTConstantExpression.parseBitOr(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
var
operatorPos: int;
op1: AVTConstant;
typeCommonRef: AVTType;
typeOperand0Ref: AVTType;
typeOperand1Ref: AVTType;
begin
pos := parseBitXor(dst, typeRef, source, pos);
while source.getLexemeType(pos) = OPER_BIT_OR do begin
operatorPos := pos;
op1 := AVTConstant.create();
try
pos := parseBitXor(op1, typeRef, source, pos + 1);
typeOperand0Ref := dst.valueType;
typeOperand1Ref := op1.valueType;
typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
if typeCommonRef is AVTTypePrimitive then begin
cast(dst, dst, AVTTypePrimitive(typeCommonRef));
cast(op1, op1, AVTTypePrimitive(typeCommonRef));
case AVTTypePrimitive(typeCommonRef).primitiveKind of
AVT_BOOLEAN: begin
dst.value.asBoolean := dst.value.asBoolean or op1.value.asBoolean;
continue;
end;
AVT_BYTE: begin
byteBitOr(dst, dst, op1);
continue;
end;
AVT_BYTE2: begin
byte2BitOr(dst, dst, op1);
continue;
end;
AVT_BYTE4: begin
byte4BitOr(dst, dst, op1);
continue;
end;
AVT_BYTE8: begin
byte8BitOr(dst, dst, op1);
continue;
end;
AVT_SHORT: begin
shortBitOr(dst, dst, op1);
continue;
end;
AVT_SHORT2: begin
short2BitOr(dst, dst, op1);
continue;
end;
AVT_SHORT4: begin
short4BitOr(dst, dst, op1);
continue;
end;
AVT_SHORT8: begin
short8BitOr(dst, dst, op1);
continue;
end;
AVT_INT: begin
intBitOr(dst, dst, op1);
continue;
end;
AVT_INT2: begin
int2BitOr(dst, dst, op1);
continue;
end;
AVT_INT4: begin
int4BitOr(dst, dst, op1);
continue;
end;
AVT_INT8: begin
int8BitOr(dst, dst, op1);
continue;
end;
AVT_LONG: begin
longBitOr(dst, dst, op1);
continue;
end;
AVT_LONG2: begin
long2BitOr(dst, dst, op1);
continue;
end;
AVT_LONG4: begin
long4BitOr(dst, dst, op1);
continue;
end;
AVT_LONG8: begin
long8BitOr(dst, dst, op1);
continue;
end;
end;
end;
finally
op1.free();
end;
raise AVTCompilerException.create('The operator | is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
end;
result := pos;
end;
function AVTConstantExpression.parseBoolAnd(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
var
operatorPos: int;
op1: AVTConstant;
typeCommonRef: AVTType;
typeOperand0Ref: AVTType;
typeOperand1Ref: AVTType;
begin
pos := parseBitOr(dst, typeRef, source, pos);
while source.getLexemeType(pos) = OPER_BOOL_AND do begin
operatorPos := pos;
op1 := AVTConstant.create();
try
pos := parseBitOr(op1, typeRef, source, pos + 1);
typeOperand0Ref := dst.valueType;
typeOperand1Ref := op1.valueType;
typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
if typeCommonRef is AVTTypePrimitive then begin
cast(dst, dst, AVTTypePrimitive(typeCommonRef));
cast(op1, op1, AVTTypePrimitive(typeCommonRef));
if typeCommonRef.isBoolean() then begin
dst.value.asBoolean := dst.value.asBoolean and op1.value.asBoolean;
continue;
end;
end;
finally
op1.free();
end;
raise AVTCompilerException.create('The operator && is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
end;
result := pos;
end;
function AVTConstantExpression.parseBoolOr(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
var
operatorPos: int;
op1: AVTConstant;
typeCommonRef: AVTType;
typeOperand0Ref: AVTType;
typeOperand1Ref: AVTType;
begin
pos := parseBoolAnd(dst, typeRef, source, pos);
while source.getLexemeType(pos) = OPER_BOOL_OR do begin
operatorPos := pos;
op1 := AVTConstant.create();
try
pos := parseBoolAnd(op1, typeRef, source, pos + 1);
typeOperand0Ref := dst.valueType;
typeOperand1Ref := op1.valueType;
typeCommonRef := commonType(typeOperand0Ref, typeOperand1Ref);
if typeCommonRef is AVTTypePrimitive then begin
cast(dst, dst, AVTTypePrimitive(typeCommonRef));
cast(op1, op1, AVTTypePrimitive(typeCommonRef));
if typeCommonRef.isBoolean() then begin
dst.value.asBoolean := dst.value.asBoolean or op1.value.asBoolean;
continue;
end;
end;
finally
op1.free();
end;
raise AVTCompilerException.create('The operator || is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref), source, operatorPos);
end;
result := pos;
end;
function AVTConstantExpression.parseConditional(dst: AVTConstant; typeRef: AVTTypeStructured; source: AVTSource; pos: int): int;
label
label0;
var
operatorPos: int;
op1: AVTConstant;
op2: AVTConstant;
typeCommonRef: AVTType;
typeOperand0Ref: AVTType;
typeOperand1Ref: AVTType;
typeOperand2Ref: AVTType;
begin
pos := parseBoolOr(dst, typeRef, source, pos);
if source.getLexemeType(pos) = CHAR_QUESTION then begin
op1 := nil;
op2 := nil;
try
op1 := AVTConstant.create();
op2 := AVTConstant.create();
pos := parseConditional(op1, typeRef, source, pos + 1);
operatorPos := pos;
if source.getLexemeType(pos) <> CHAR_COLON then begin
raise AVTCompilerException.create('":" expected', source, pos);
end;
pos := parseConditional(op2, typeRef, source, pos + 1);
typeOperand0Ref := dst.valueType;
typeOperand1Ref := op1.valueType;
typeOperand2Ref := op2.valueType;
if (typeOperand0Ref <> nil) and typeOperand0Ref.isBoolean() then begin
typeCommonRef := commonType(typeOperand1Ref, typeOperand2Ref);
if (typeCommonRef = nil) or (typeCommonRef is AVTTypeStructured) then begin
op1.valueType := typeCommonRef;
op2.valueType := typeCommonRef;
end else
if typeCommonRef is AVTTypePrimitive then begin
cast(op1, op1, AVTTypePrimitive(typeCommonRef));
cast(op2, op2, AVTTypePrimitive(typeCommonRef));
end else begin
goto label0;
end;
if dst.value.asBoolean = true then begin
dst.assign(op1);
end else begin
dst.assign(op2);
end;
{ continue; }
result := pos;
exit;
end;
label0:
finally
op1.free();
op2.free();
end;
raise AVTCompilerException.create('The operator ?: is undefined for the argument types ' + itemToString(typeOperand0Ref) + ', ' + itemToString(typeOperand1Ref) + ', ' + itemToString(typeOperand2Ref), source, operatorPos);
end;
result := pos;
end;
function AVTConstantExpression.tryParseType(typeRef: AVTTypeStructured; source: AVTSource; pos: int): AVTType;
var
lxt: int;
dimensions: int;
app: AVTProgramme;
itemParsedRef: AVTItem;
typeParsedRef: AVTType;
begin
app := programme;
lxt := source.getLexemeType(pos);
if lxt = AVT_VOID then begin
source.position := pos + 1;
result := app.systemPackage.getType(AVTTypePrimitive.getName(AVT_VOID));
exit;
end;
typeParsedRef := nil;
if (lxt >= AVT_BOOLEAN) and (lxt <= AVT_DOUBLE8) then begin
typeParsedRef := app.systemPackage.getType(AVTTypePrimitive.getName(lxt));
inc(pos);
end else
if lxt = LITR_NAME then begin
itemParsedRef := resolveName(source.getLexemeAnsiString(pos), typeRef, pos);
if itemParsedRef is AVTPackage then begin
typeParsedRef := tryParseFullyQualifiedTypeName(AVTPackage(itemParsedRef), typeRef, pos + 1);
pos := source.position;
end else
if itemParsedRef is AVTType then begin
typeParsedRef := AVTType(itemParsedRef);
inc(pos);
end;
end;
if typeParsedRef = nil then begin
result := nil;
exit;
end;
dimensions := 0;
while (dimensions < 99) and (source.getLexemeType(pos) = CHAR_BRACKET_OPENED) and (source.getLexemeType(pos + 1) = CHAR_BRACKET_CLOSED) do begin
typeParsedRef := app.getArrayOf(typeParsedRef);
inc(dimensions);
inc(pos, 2);
end;
source.position := pos;
result := typeParsedRef;
end;
procedure AVTConstantExpression.parseFieldInitialValue(fieldRef: AVTField);
var
newClinit: boolean;
pos: int;
code: AVTCode;
node: AVTNode;
source: AVTSource;
copy: AVTConstant;
value: AVTConstant;
fieldType: AVTType;
constType: AVTType;
methodRef: AVTMethod;
typeVoidRef: AVTType;
typeRef: AVTTypeStructured;
begin
pos := fieldRef.implementationPosition;
if (pos < 0) or fieldRef.valueConstCreated then exit;
source := fieldRef.source;
fieldRef.makeValueConstCreating();
try
value := fieldRef.createValueConst();
pos := parseConstantExpression(value, fieldRef.parentType, pos);
fieldType := fieldRef.valueType;
constType := value.valueType;
if not fieldType.isConvertableFrom(constType) then begin
raise AVTCompilerException.create('Can not assign value of the type ' + itemToString(constType) + ' to field of the type ' + itemToString(fieldType), source, pos);
end;
if fieldType is AVTTypePrimitive then begin
cast(value, value, AVTTypePrimitive(fieldType));
end else begin
value.valueType := fieldType;
end;
finally
fieldRef.makeValueConstCreated();
end;
if source.getLexemeType(pos) <> CHAR_SEMICOLON then begin
raise AVTCompilerException.create('";" expected', source, pos);
end;
if ((fieldRef.flags and (FLAG_STATIC or FLAG_FINAL)) = FLAG_STATIC) and (fieldType is AVTTypeStructured) and not value.value.isNull then begin
typeRef := fieldRef.parentType;
with typeRef.members(SPECNAME_CLASS_INIT) do begin
if hasMoreElements() then begin
newClinit := false;
methodRef := nextElement().objectValue() as AVTMethod;
end else begin
newClinit := true;
methodRef := AVTClassInit.create(typeRef, -1);
end;
end;
typeVoidRef := getPrimitiveType(AVT_VOID);
code := methodRef.code;
node := code.root;
if newClinit then begin
node.setData(-1, typeVoidRef, AVT_ENTER);
end;
copy := AVTConstant.create();
copy.assign(value);
node := code.appendNode(node, -1, typeVoidRef, STORE_STATIC, fieldRef);
code.appendNode(node).setData(-1, fieldType, LOAD_CONST, copy);
end;
end;
procedure AVTConstantExpression.parsePropertyImplementation(propertyRef: AVTProperty);
label
label0;
var
isAbstract: boolean;
isConstant: boolean;
hasIndex: boolean;
hasRead: boolean;
hasWrite: boolean;
hasStored: boolean;
pos: int;
writePos: int;
storedPos: int;
argumentIndex: int;
name: AnsiString;
itemRef: AVTItem;
fieldRef: AVTField;
methodRef: AVTMethod;
arguments: Vector;
source: AVTSource;
constant: AVTConstant;
typeConstantRef: AVTType;
typePropertyRef: AVTType;
typeArgumentRef: AVTType;
typeRef: AVTTypeStructured;
overriddenRef: AVTProperty;
begin
pos := propertyRef.implementationPosition;
if pos < 0 then exit;
source := propertyRef.source;
typeRef := propertyRef.parentType;
typePropertyRef := propertyRef.valueType;
isAbstract := propertyRef.isAbstract();
hasIndex := false;
hasRead := false;
hasWrite := false;
hasStored := false;
writePos := -1;
storedPos := -1;
begin
{ INDEX }
if (source.getLexemeType(pos) = LITR_NAME) and (source.getLexemeAnsiString(pos) = 'index') then begin
if isAbstract then begin
raise AVTCompilerException.create('The index specifier is an invalid specifier for an abstract property', source, pos);
end;
inc(pos);
if source.getLexemeType(pos) <> CHAR_EQUALS then begin
raise AVTCompilerException.create('"=" expected', source, pos);
end;
inc(pos);
constant := AVTConstant.create();
try
pos := parseConstantExpression(constant, typeRef, pos);
typeConstantRef := constant.valueType;
if not(typeConstantRef is AVTTypePrimitive) then begin
raise AVTCompilerException.create('Type mismatch: can not convert from ' + itemToString(typeConstantRef) + ' to int', source, pos);
end;
case AVTTypePrimitive(typeConstantRef).primitiveKind of
AVT_BYTE: begin
propertyRef.index := constant.value.asByte;
end;
AVT_SHORT: begin
propertyRef.index := constant.value.asShort;
end;
AVT_INT: begin
propertyRef.index := constant.value.asInt;
end
else
raise AVTCompilerException.create('Type mismatch: can not convert from ' + itemToString(typeConstantRef) + ' to int', source, pos);
end;
finally
constant.free();
end;
hasIndex := true;
if source.getLexemeType(pos) <> CHAR_COMMA then goto label0;
inc(pos);
end;
{ READ }
if (source.getLexemeType(pos) = LITR_NAME) and (source.getLexemeAnsiString(pos) = 'read') then begin
inc(pos);
if isAbstract then begin
propertyRef.readMember := nil;
end else begin
if source.getLexemeType(pos) <> CHAR_EQUALS then begin
raise AVTCompilerException.create('"=" expected', source, pos);
end;
inc(pos);
isConstant := true;
if source.getLexemeType(pos) = LITR_NAME then begin
name := source.getLexemeAnsiString(pos);
itemRef := resolveName(name, typeRef, pos);
if (itemRef is AVTField) and not itemRef.isStatic() then begin
fieldRef := AVTField(itemRef);
if not typePropertyRef.isAssignableFrom(fieldRef.valueType) then begin
raise AVTCompilerException.create('The field ' + fieldRef.simpleName + ' can not be used as the read member for the property ' + propertyRef.simpleName, source, pos);
end;
propertyRef.readMember := fieldRef;
isConstant := false;
inc(pos);
end else
if itemRef is AVTMethod then begin
arguments := Vector.create();
try
if hasIndex then begin
arguments.append(ValueOfObject.create(getPrimitiveType(AVT_INT), false));
end;
methodRef := typeRef.findMethod(name, arguments, typeRef, pos);
if methodRef.isStatic() or not typePropertyRef.isAssignableFrom(methodRef.returnType) then begin
raise AVTCompilerException.create('The method ' + methodRef.simpleName + methodRef.argumentsToString() + ' in the type ' + methodRef.parentType.fullName + ' can not be used as the read member for the property ' + propertyRef.simpleName, source, pos);
end;
if not methodRef.isIdentityArgumentTypes(arguments) then begin
raise AVTCompilerException.create('The method ' + methodRef.simpleName + methodRef.argumentsToString() + ' in the type ' + methodRef.parentType.fullName + ' is not applicable for the arguments ' + arguments.toString(), source, pos);
end;
finally
arguments.free();
end;
if not methodRef.isVisible(typeRef, typeRef) then begin
raise AVTCompilerException.create('The method ' + methodRef.simpleName + methodRef.argumentsToString() + ' from the type ' + methodRef.parentType.fullName + ' is not visible', source, pos);
end;
if methodRef.mightThrown() then begin
raise AVTCompilerException.create('The method ' + methodRef.simpleName + methodRef.argumentsToString() + ' in the type ' + methodRef.parentType.fullName + ' can throw an exception', source, pos);
end;
propertyRef.readMember := methodRef;
isConstant := false;
inc(pos);
end;
end;
if isConstant then begin
constant := AVTConstant.create();
try
pos := parseConstantExpression(constant, typeRef, pos);
typeConstantRef := constant.valueType;
if not typePropertyRef.isConvertableFrom(typeConstantRef) then begin
raise AVTCompilerException.create('Type mismatch: can not convert from ' + itemToString(typeConstantRef) + ' to ' + itemToString(typePropertyRef), source, pos);
end;
if typePropertyRef is AVTTypePrimitive then begin
cast(constant, constant, AVTTypePrimitive(typePropertyRef));
end else begin
constant.valueType := typePropertyRef;
end;
propertyRef.readMember := constant;
finally
constant.free();
end;
end;
end;
hasRead := true;
if source.getLexemeType(pos) <> CHAR_COMMA then goto label0;
inc(pos);
end;
{ WRITE }
writePos := pos;
if (source.getLexemeType(pos) = LITR_NAME) and (source.getLexemeAnsiString(pos) = 'write') then begin
inc(pos);
if isAbstract then begin
propertyRef.writeMember := nil;
end else begin
if source.getLexemeType(pos) <> CHAR_EQUALS then begin
raise AVTCompilerException.create('"=" expected', source, pos);
end;
inc(pos);
isConstant := true;
if source.getLexemeType(pos) = LITR_NAME then begin
name := source.getLexemeAnsiString(pos);
itemRef := resolveName(name, typeRef, pos);
if (itemRef is AVTField) and not itemRef.isStatic() then begin
fieldRef := AVTField(itemRef);
if fieldRef.isFinal() or not fieldRef.valueType.isAssignableFrom(typePropertyRef) then begin
raise AVTCompilerException.create('The field ' + fieldRef.simpleName + ' can not be used as the write member for the property ' + propertyRef.simpleName, source, pos);
end;
propertyRef.writeMember := fieldRef;
isConstant := false;
inc(pos);
end else
if itemRef is AVTMethod then begin
arguments := Vector.create();
try
if hasIndex then begin
arguments.append(ValueOfObject.create(getPrimitiveType(AVT_INT), false));
end;
arguments.append(ValueOfObject.create(typePropertyRef, false));
methodRef := typeRef.findMethod(name, arguments, typeRef, pos);
if methodRef.isStatic() or not methodRef.returnType.isVoid() then begin
raise AVTCompilerException.create('The method ' + methodRef.simpleName + methodRef.argumentsToString() + ' in the type ' + methodRef.parentType.fullName + ' can not be used as the write member for the property ' + propertyRef.simpleName, source, pos);
end;
if methodRef.getArgumentsCount() <> arguments.size() then begin
raise AVTCompilerException.create('The method ' + methodRef.simpleName + methodRef.argumentsToString() + ' in the type ' + methodRef.parentType.fullName + ' is not applicable for the arguments ' + arguments.toString(), source, pos);
end;
argumentIndex := 0;
if hasIndex then begin
typeArgumentRef := methodRef.getArgumentAt(0).valueType;
if not(typeArgumentRef is AVTTypePrimitive) or (AVTTypePrimitive(typeArgumentRef).primitiveKind <> AVT_INT) then begin
raise AVTCompilerException.create('The method ' + methodRef.simpleName + methodRef.argumentsToString() + ' in the type ' + methodRef.parentType.fullName + ' is not applicable for the arguments ' + arguments.toString(), source, pos);
end;
inc(argumentIndex);
end;
typeArgumentRef := methodRef.getArgumentAt(argumentIndex).valueType;
if not typeArgumentRef.isAssignableFrom(typePropertyRef) then begin
raise AVTCompilerException.create('The method ' + methodRef.simpleName + methodRef.argumentsToString() + ' in the type ' + methodRef.parentType.fullName + ' is not applicable for the arguments ' + arguments.toString(), source, pos);
end;
finally
arguments.free();
end;
if not methodRef.isVisible(typeRef, typeRef) then begin
raise AVTCompilerException.create('The method ' + methodRef.simpleName + methodRef.argumentsToString() + ' from the type ' + methodRef.parentType.fullName + ' is not visible', source, pos);
end;
if methodRef.mightThrown() then begin
raise AVTCompilerException.create('The method ' + methodRef.simpleName + methodRef.argumentsToString() + ' in the type ' + methodRef.parentType.fullName + ' can throw an exception', source, pos);
end;
propertyRef.writeMember := methodRef;
isConstant := false;
inc(pos);
end;
end;
if isConstant then begin
raise AVTCompilerException.create('Write member expected', source, pos);
end;
end;
hasWrite := true;
if source.getLexemeType(pos) <> CHAR_COMMA then goto label0;
inc(pos);
end;
{ STORED }
storedPos := pos;
if (source.getLexemeType(pos) = LITR_NAME) and (source.getLexemeAnsiString(pos) = 'stored') then begin
if isAbstract then begin
raise AVTCompilerException.create('The stored specifier is an invalid specifier for an abstract property', source, pos);
end;
inc(pos);
if source.getLexemeType(pos) <> CHAR_EQUALS then begin
raise AVTCompilerException.create('"=" expected', source, pos);
end;
inc(pos);
isConstant := true;
if source.getLexemeType(pos) = LITR_NAME then begin
name := source.getLexemeAnsiString(pos);
itemRef := resolveName(name, typeRef, pos);
if (itemRef is AVTField) and not itemRef.isStatic() then begin
fieldRef := AVTField(itemRef);
if not fieldRef.valueType.isBoolean() then begin
raise AVTCompilerException.create('The field ' + fieldRef.simpleName + ' can not be used as the stored member for the property ' + propertyRef.simpleName, source, pos);
end;
propertyRef.storedMember := fieldRef;
isConstant := false;
inc(pos);
end else
if itemRef is AVTMethod then begin
arguments := Vector.create();
try
if hasIndex then begin
arguments.append(ValueOfObject.create(getPrimitiveType(AVT_INT), false));
end;
methodRef := typeRef.findMethod(name, arguments, typeRef, pos);
if methodRef.isStatic() or not methodRef.returnType.isBoolean() then begin
raise AVTCompilerException.create('The method ' + methodRef.simpleName + methodRef.argumentsToString() + ' in the type ' + methodRef.parentType.fullName + ' can not be used as the stored member for the property ' + propertyRef.simpleName, source, pos);
end;
if not methodRef.isIdentityArgumentTypes(arguments) then begin
raise AVTCompilerException.create('The method ' + methodRef.simpleName + methodRef.argumentsToString() + ' in the type ' + methodRef.parentType.fullName + ' is not applicable for the arguments ' + arguments.toString(), source, pos);
end;
finally
arguments.free();
end;
if not methodRef.isVisible(typeRef, typeRef) then begin
raise AVTCompilerException.create('The method ' + methodRef.simpleName + methodRef.argumentsToString() + ' from the type ' + methodRef.parentType.fullName + ' is not visible', source, pos);
end;
if methodRef.mightThrown() then begin
raise AVTCompilerException.create('The method ' + methodRef.simpleName + methodRef.argumentsToString() + ' in the type ' + methodRef.parentType.fullName + ' can throw an exception', source, pos);
end;
propertyRef.storedMember := methodRef;
isConstant := false;
inc(pos);
end;
end;
if isConstant then begin
constant := AVTConstant.create();
try
pos := parseConstantExpression(constant, typeRef, pos);
typeConstantRef := constant.valueType;
if (typeConstantRef = nil) or not typeConstantRef.isBoolean() then begin
raise AVTCompilerException.create('Type mismatch: can not convert from ' + itemToString(typeConstantRef) + ' to boolean', source, pos);
end;
propertyRef.storedMember := constant;
finally
constant.free();
end;
end;
hasStored := true;
end;
end;
label0:
if source.getLexemeType(pos) <> CHAR_CURLY_CLOSED then begin
raise AVTCompilerException.create('"}" expected', source, pos);
end;
if not hasRead and not hasWrite then begin
raise AVTCompilerException.create('The read or write specifier is required for a property', source, pos);
end;
if storedPos < 0 then storedPos := pos;
if writePos < 0 then writePos := storedPos;
with propertyRef.overriddenMembers() do while hasMoreElements() do begin
overriddenRef := nextElement().objectValue() as AVTProperty;
if (overriddenRef.readSynthetic <> nil) and not hasRead then begin
raise AVTCompilerException.create('The inherited property ' + overriddenRef.simpleName + ' in the type ' + overriddenRef.parentType.fullName + ' requires the read specifier', source, writePos);
end;
if (overriddenRef.writeSynthetic <> nil) and not hasWrite then begin
raise AVTCompilerException.create('The inherited property ' + overriddenRef.simpleName + ' in the type ' + overriddenRef.parentType.fullName + ' requires the write specifier', source, storedPos);
end;
if (overriddenRef.storedSynthetic <> nil) and not hasStored then begin
hasStored := true;
if isAbstract then begin
propertyRef.storedMember := nil;
end else begin
constant := AVTConstant.create(getPrimitiveType(AVT_BOOLEAN));
try
constant.value.asBoolean := false;
propertyRef.storedMember := constant;
finally
constant.free();
end;
end;
end;
end;
end;
function AVTConstantExpression.parseConstantExpression(dst: AVTConstant; typeRef: AVTTypeStructured; pos: int): int;
begin
result := parseConditional(dst, typeRef, typeRef.source, pos);
end;
function AVTConstantExpression.parseType(typeRef: AVTTypeStructured; pos: int): AVTType;
var
lxt: int;
dimensions: int;
app: AVTProgramme;
source: AVTSource;
itemParsedRef: AVTItem;
typeParsedRef: AVTType;
begin
app := programme;
source := typeRef.source;
lxt := source.getLexemeType(pos);
if lxt = AVT_VOID then begin
source.position := pos + 1;
result := app.systemPackage.getType(AVTTypePrimitive.getName(AVT_VOID));
exit;
end;
typeParsedRef := nil;
if (lxt >= AVT_BOOLEAN) and (lxt <= AVT_DOUBLE8) then begin
typeParsedRef := app.systemPackage.getType(AVTTypePrimitive.getName(lxt));
inc(pos);
end else
if lxt = LITR_NAME then begin
itemParsedRef := resolveName(source.getLexemeAnsiString(pos), typeRef, pos);
if itemParsedRef is AVTPackage then begin
typeParsedRef := parseFullyQualifiedTypeName(AVTPackage(itemParsedRef), typeRef, pos + 1);
pos := source.position;
end else
if itemParsedRef is AVTType then begin
typeParsedRef := AVTType(itemParsedRef);
inc(pos);
end;
end;
if typeParsedRef = nil then begin
raise AVTCompilerException.create('Type expected', source, pos);
end;
dimensions := 0;
while (dimensions < 99) and (source.getLexemeType(pos) = CHAR_BRACKET_OPENED) and (source.getLexemeType(pos + 1) = CHAR_BRACKET_CLOSED) do begin
typeParsedRef := app.getArrayOf(typeParsedRef);
inc(dimensions);
inc(pos, 2);
end;
source.position := pos;
result := typeParsedRef;
end;
function AVTConstantExpression.resolveName(const simpleName: AnsiString; typeRef: AVTTypeStructured; pos: int): AVTItem;
label
label0;
var
item: AVTItem;
source: AVTSource;
begin
source := typeRef.source;
item := typeRef.getMember(simpleName);
if (item is AVTField) or (item is AVTProperty) then begin
item := typeRef.findField(simpleName, typeRef, pos);
end;
if item = nil then begin
item := source.getDeclaredType(simpleName);
if item <> nil then goto label0;
item := source.getImportedType(simpleName);
if item <> nil then goto label0;
item := source.package.getType(simpleName);
if item <> nil then goto label0;
item := source.findImportedType(simpleName, typeRef, pos);
if item <> nil then goto label0;
item := programme.getPackage(simpleName);
end;
label0:
if not(item is AVTMethod) and (item is AVTItemExt) and not AVTItemExt(item).isVisible(typeRef, typeRef) then begin
if item is AVTMember then begin
raise AVTCompilerException.create('The field ' + simpleName + ' is not visible', source, pos);
end;
raise AVTCompilerException.create('The type ' + simpleName + ' is not visible', source, pos);
end;
result := item;
end;
procedure AVTConstantExpression.cast(dst, op0: AVTConstant; typeNewRef: AVTTypePrimitive);
var
i: int;
len1: int;
len2: int;
base1: int;
base2: int;
typeNewKind: int;
typeRef: AVTType;
typeSrcRef: AVTTypePrimitive;
begin
if dst = nil then begin
raise NullPointerException.create('AVTConstantExpression.cast: ' + msgNullPointerArgument + 'dst');
end;
if op0 = nil then begin
raise NullPointerException.create('AVTConstantExpression.cast: ' + msgNullPointerArgument + 'op0');
end;
if typeNewRef = nil then begin
raise NullPointerException.create('AVTConstantExpression.cast: ' + msgNullPointerArgument + 'typeNewRef');
end;
typeRef := op0.valueType;
if not(typeRef is AVTTypePrimitive) or typeRef.isVoid() then begin
raise IllegalArgumentException.create('AVTConstantExpression.cast: ' + msgIllegalArgument + 'op0');
end;
typeNewKind := typeNewRef.primitiveKind;
if typeNewKind = AVT_VOID then begin
raise IllegalArgumentException.create('AVTConstantExpression.cast: ' + msgIllegalArgument + 'typeNewRef');
end;
if dst <> op0 then dst.assignValue(op0);
typeSrcRef := AVTTypePrimitive(typeRef);
len1 := typeSrcRef.compoundLength;
len2 := typeNewRef.compoundLength;
base1 := typeSrcRef.compoundBase;
base2 := typeNewRef.compoundBase;
if base1 > AVT_REAL then for i := intMin(len1, len2) to 7 do begin
case base1 of
AVT_BYTE: dst.value.asByte8[i] := 0;
AVT_SHORT: dst.value.asShort8[i] := 0;
AVT_INT: dst.value.asInt8[i] := 0;
AVT_LONG: dst.value.asLong8[i] := 0;
AVT_FLOAT: dst.value.asFloat8[i] := 0.0;
AVT_DOUBLE: dst.value.asDouble8[i] := 0.0;
end;
end;
if base1 = AVT_CHAR then begin
base1 := AVT_INT;
dst.value.asInt := int(dst.value.asChar);
end;
case base2 of
AVT_BYTE: begin
case base1 of
AVT_SHORT: castShort8ToByte8(dst, dst, typeNewKind);
AVT_INT: castInt8ToByte8(dst, dst, typeNewKind);
AVT_LONG: castLong8ToByte8(dst, dst, typeNewKind);
AVT_FLOAT: castFloat8ToByte8(dst, dst, typeNewKind);
AVT_DOUBLE: castDouble8ToByte8(dst, dst, typeNewKind);
AVT_REAL: castRealToByte8(dst, dst, typeNewKind);
else dst.valueType := typeNewRef;
end;
end;
AVT_SHORT: begin
case base1 of
AVT_BYTE: castByte8ToShort8(dst, dst, typeNewKind);
AVT_INT: castInt8ToShort8(dst, dst, typeNewKind);
AVT_LONG: castLong8ToShort8(dst, dst, typeNewKind);
AVT_FLOAT: castFloat8ToShort8(dst, dst, typeNewKind);
AVT_DOUBLE: castDouble8ToShort8(dst, dst, typeNewKind);
AVT_REAL: castRealToShort8(dst, dst, typeNewKind);
else dst.valueType := typeNewRef;
end;
end;
AVT_INT, AVT_CHAR: begin
case base1 of
AVT_BYTE: castByte8ToInt8(dst, dst, typeNewKind);
AVT_SHORT: castShort8ToInt8(dst, dst, typeNewKind);
AVT_LONG: castLong8ToInt8(dst, dst, typeNewKind);
AVT_FLOAT: castFloat8ToInt8(dst, dst, typeNewKind);
AVT_DOUBLE: castDouble8ToInt8(dst, dst, typeNewKind);
AVT_REAL: castRealToInt8(dst, dst, typeNewKind);
else dst.valueType := typeNewRef;
end;
end;
AVT_LONG: begin
case base1 of
AVT_BYTE: castByte8ToLong8(dst, dst, typeNewKind);
AVT_SHORT: castShort8ToLong8(dst, dst, typeNewKind);
AVT_INT: castInt8ToLong8(dst, dst, typeNewKind);
AVT_FLOAT: castFloat8ToLong8(dst, dst, typeNewKind);
AVT_DOUBLE: castDouble8ToLong8(dst, dst, typeNewKind);
AVT_REAL: castRealToLong8(dst, dst, typeNewKind);
else dst.valueType := typeNewRef;
end;
end;
AVT_FLOAT: begin
case base1 of
AVT_BYTE: castByte8ToFloat8(dst, dst, typeNewKind);
AVT_SHORT: castShort8ToFloat8(dst, dst, typeNewKind);
AVT_INT: castInt8ToFloat8(dst, dst, typeNewKind);
AVT_LONG: castLong8ToFloat8(dst, dst, typeNewKind);
AVT_DOUBLE: castDouble8ToFloat8(dst, dst, typeNewKind);
AVT_REAL: castRealToFloat8(dst, dst, typeNewKind);
else dst.valueType := typeNewRef;
end;
end;
AVT_DOUBLE: begin
case base1 of
AVT_BYTE: castByte8ToDouble8(dst, dst, typeNewKind);
AVT_SHORT: castShort8ToDouble8(dst, dst, typeNewKind);
AVT_INT: castInt8ToDouble8(dst, dst, typeNewKind);
AVT_LONG: castLong8ToDouble8(dst, dst, typeNewKind);
AVT_FLOAT: castFloat8ToDouble8(dst, dst, typeNewKind);
AVT_REAL: castRealToDouble8(dst, dst, typeNewKind);
else dst.valueType := typeNewRef;
end;
end;
AVT_REAL: begin
case base1 of
AVT_BYTE: castByte8ToReal(dst, dst, typeNewKind);
AVT_SHORT: castShort8ToReal(dst, dst, typeNewKind);
AVT_INT: castInt8ToReal(dst, dst, typeNewKind);
AVT_LONG: castLong8ToReal(dst, dst, typeNewKind);
AVT_FLOAT: castFloat8ToReal(dst, dst, typeNewKind);
AVT_DOUBLE: castDouble8ToReal(dst, dst, typeNewKind);
else dst.valueType := typeNewRef;
end;
end
else
dst.valueType := typeNewRef;
end;
if base2 = AVT_CHAR then begin
dst.value.asChar := wchar(dst.value.asInt);
end;
end;
function AVTConstantExpression.getPrimitiveType(kind: int): AVTTypePrimitive;
begin
result := programme.systemPackage.getType(AVTTypePrimitive.getName(kind)) as AVTTypePrimitive;
end;
function AVTConstantExpression.getStringType(): AVTTypeStructured;
var
packageAvtLangRef: AVTPackage;
typeStringRef: AVTTypeStructured;
begin
typeStringRef := fldTypeStringRef;
if typeStringRef <> nil then begin
result := typeStringRef;
exit;
end;
packageAvtLangRef := programme.getPackage('avt.lang');
if packageAvtLangRef = nil then begin
result := nil;
exit;
end;
typeStringRef := packageAvtLangRef.getType('String') as AVTTypeStructured;
fldTypeStringRef := typeStringRef;
result := typeStringRef;
end;
function AVTConstantExpression.getClassType(): AVTTypeStructured;
var
packageAvtLangRef: AVTPackage;
typeClassRef: AVTTypeStructured;
begin
typeClassRef := fldTypeClassRef;
if typeClassRef <> nil then begin
result := typeClassRef;
exit;
end;
packageAvtLangRef := programme.getPackage('avt.lang');
if packageAvtLangRef = nil then begin
result := nil;
exit;
end;
typeClassRef := packageAvtLangRef.getType('Class') as AVTTypeStructured;
fldTypeClassRef := typeClassRef;
result := typeClassRef;
end;
{%endregion}
end.