{
Этот исходный текст является частью Продвинутого векторного транслятора.
Copyright © 2017 Малик Разработчик
Это свободная программа: вы можете перераспространять её и/или
изменять её на условиях Стандартной общественной лицензии GNU в том виде,
в каком она была опубликована Фондом свободного программного обеспечения;
либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.
Эта программа распространяется в надежде, что она может быть полезна,
но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЁННЫХ ЦЕЛЕЙ. Подробнее см. в Стандартной
общественной лицензии GNU.
Вы должны были получить копию Стандартной общественной лицензии GNU
вместе с этой программой. Если это не так, см.
<http://www.gnu.org/licenses/>.
}
unit TranType;
{$MODE DELPHI,EXTENDEDSYNTAX ON}
interface
uses
Lang, TranIntf;
{$ASMMODE INTEL,CALLING REGISTER,INLINE ON,GOTO ON}
{$H+,I-,J-,M-,Q-,R-,T-}
type
TranslatorType = class;
TranslatorTypePrimitive = class;
TranslatorTypeArray = class;
TranslatorTypeFunction = class;
TranslatorTypeStructure = class;
TranslatorNameAndTypeObject = class;
TranslatorLocalVariable = class;
TranslatorStructureField = class;
TranslatorType = class(RefCountInterfacedObject, TypeDescriptor)
public //доступен| общий
const KIND_VOID = $0000; // везде |
const KIND_BOOLEAN = $0001; // везде | везде
const KIND_CHAR = $0002; // везде |
const KIND_BYTE = $0101; // везде |
const KIND_SHORT = $0102; // везде | 16
const KIND_INT = $0104; // 32, 64 | 32, 64
const KIND_LONG = $0108; // 64 | 64
const KIND_ULTRA = $0210; // 64 | 64
const KIND_FLOAT = $0304; // везде | везде
const KIND_DOUBLE = $0308; // везде | везде
const KIND_REAL = $030a; // везде | везде
const KIND_XVECTOR = $0410; // 64 | 64
const KIND_STRUCT = $0500; // везде
const KIND_ARRAY = $0600; // везде
const KIND_FUNC = $0700; // везде
const SIZE_16_BIT = $0002;
const SIZE_32_BIT = $0004;
const SIZE_64_BIT = $0008;
public
constructor create(kind: int);
function possibleCastTo(typeForTest: TypeDescriptor): boolean; virtual; abstract;
function possibleAssignTo(typeForTest: TypeDescriptor): boolean; virtual; abstract;
function isMatchForConstant(): boolean; virtual;
function isMatchForVariable(): boolean; virtual;
function isMatchForReturnType(): boolean; virtual;
function getAlignedSize(operandSize: int): int; virtual;
function getKind(): int; virtual;
function getSize(): int; virtual;
private
kind: int;
end;
TranslatorTypePrimitive = class(TranslatorType, TypePrimitive)
public
function equals(obj: TObject): boolean; override;
function getHashCode(): int; override;
function toString(): AnsiString; override;
function possibleCastTo(typeForTest: TypeDescriptor): boolean; override;
function possibleAssignTo(typeForTest: TypeDescriptor): boolean; override;
function possibleAssignLong(value: long): boolean; virtual;
end;
TranslatorTypeArray = class(TranslatorType, TypeArray)
public
constructor create(operandSize: int; elementType: TypeDescriptor);
function equals(obj: TObject): boolean; override;
function getHashCode(): int; override;
function toString(): AnsiString; override;
function possibleCastTo(typeForTest: TypeDescriptor): boolean; override;
function possibleAssignTo(typeForTest: TypeDescriptor): boolean; override;
function getDimensions(): int; virtual;
function getCellType(): TypeDescriptor; virtual;
function getElementType(): TypeDescriptor; virtual;
strict private
dimensions: int;
cellType: TypeDescriptor;
elementType: TypeDescriptor;
textRepresentation: AnsiString;
end;
TranslatorTypeFunction = class(TranslatorType, TypeFunction)
public
constructor create(operandSize: int; returnType: TypeDescriptor);
function equals(obj: TObject): boolean; override;
function getHashCode(): int; override;
function toString(): AnsiString; override;
function possibleCastTo(typeForTest: TypeDescriptor): boolean; override;
function possibleAssignTo(typeForTest: TypeDescriptor): boolean; override;
function getArgumentsSize(): int; virtual;
function getArgumentsCount(): int; virtual;
function getReturnType(): TypeDescriptor; virtual;
function getArgument(index: int): FunctionArgument; virtual;
function findArgument(const argName: UnicodeString): FunctionArgument; virtual;
function addArgument(argType: TypeDescriptor;
const argName: UnicodeString): FunctionArgument; virtual;
strict private
argSize: int;
argCount: int;
returnType: TypeDescriptor;
arguments: FunctionArgument_Array1d;
end;
TranslatorTypeStructure = class(TranslatorType, TypeStructure, NamedObject, NamespaceEntry)
public
constructor create(entryOwner: Namespace; entryPublic: boolean;
const entryName: UnicodeString; operandSize: int;
ancestorStructure: TypeStructure);
function toString(): AnsiString; override;
function possibleCastTo(typeForTest: TypeDescriptor): boolean; override;
function possibleAssignTo(typeForTest: TypeDescriptor): boolean; override;
procedure clear(); virtual;
procedure updateSize(); virtual;
function isInheritedFrom(ancestorForTest: TypeStructure): boolean; virtual;
function getStructureSize(): int; virtual;
function getFieldsCount(): int; virtual;
function getAncestor(): TypeStructure; virtual;
function getField(index: int): StructureField; virtual;
function findField(const fldName: UnicodeString;
findInAncestors: boolean): StructureField; virtual;
function addField(fldPublic: boolean; fldType: TypeDescriptor;
const fldName: UnicodeString): StructureField; virtual;
procedure setDeclarePosition(declarePosition: int); virtual;
procedure setStartPosition(startPosition: int); virtual;
function getDeclarePosition(): int; virtual;
function getStartPosition(): int; virtual;
function getName(): UnicodeString; virtual;
function isPublic(): boolean; virtual;
function getOwner(): Namespace; virtual;
strict private
entryPublic: boolean;
fldSize: int;
fldCount: int;
startPosition: int;
declarePosition: int;
entryOwner: Namespace;
ancestor: TypeStructure;
fields: StructureField_Array1d;
entryName: UnicodeString;
textRepresentation: AnsiString;
end;
TranslatorNameAndTypeObject = class(RefCountInterfacedObject, NamedObject, NameAndType)
public
constructor create(objType: TypeDescriptor; const objName: UnicodeString);
function toString(): AnsiString; override;
procedure setDeclarePosition(declarePosition: int); virtual;
procedure setStartPosition(startPosition: int); virtual;
function getDeclarePosition(): int; virtual;
function getStartPosition(): int; virtual;
function getName(): UnicodeString; virtual;
function getDataType(): TypeDescriptor; virtual;
strict private
startPosition: int;
declarePosition: int;
objType: TypeDescriptor;
objName: UnicodeString;
textRepresentation: AnsiString;
end;
TranslatorLocalVariable = class(TranslatorNameAndTypeObject, LocalVariable)
public
constructor create(varType: TypeDescriptor; const varName: UnicodeString);
end;
TranslatorStructureField = class(TranslatorNameAndTypeObject, StructureField)
public
constructor create(fldOwner: TypeStructure; fldOffset: int;
fldPublic: boolean; fldType: TypeDescriptor; const fldName: UnicodeString);
function toString(): AnsiString; override;
function isPublic(): boolean; virtual;
function getOffset(): int; virtual;
function getOwner(): TypeStructure; virtual;
strict private
fldPublic: boolean;
fldOffset: int;
fldOwner: TypeStructure;
textRepresentation: AnsiString;
end;
implementation
type
TranslatorFunctionArgument = class;
TranslatorFunctionArgument = class(TranslatorLocalVariable, FunctionArgument)
public
constructor create(argType: TypeDescriptor; const argName: UnicodeString);
end;
{ TranslatorType }
constructor TranslatorType.create(kind: int);
begin
inherited create();
self.kind := kind;
end;
function TranslatorType.isMatchForConstant(): boolean;
begin
result := (kind > $0000) and (kind < $0500);
end;
function TranslatorType.isMatchForVariable(): boolean;
begin
result := (kind and $00ff) > 0;
end;
function TranslatorType.isMatchForReturnType(): boolean;
begin
result := true;
end;
function TranslatorType.getAlignedSize(operandSize: int): int;
var
typeSize: int;
begin
if operandSize <= 0 then begin
result := 0;
exit;
end;
typeSize := kind and $00ff;
if (typeSize mod operandSize) <= 0 then begin
result := typeSize;
exit;
end;
result := (typeSize and (-operandSize)) + operandSize;
end;
function TranslatorType.getKind(): int;
begin
if kind >= $0500 then begin
result := kind and $ff00;
end else begin
result := kind;
end;
end;
function TranslatorType.getSize(): int;
begin
result := kind and $ff;
end;
{ TranslatorTypePrimitive }
function TranslatorTypePrimitive.equals(obj: TObject): boolean;
begin
result := (obj = self) or (obj is TranslatorTypePrimitive) and
(TranslatorTypePrimitive(obj).kind = kind);
end;
function TranslatorTypePrimitive.getHashCode(): int;
begin
result := kind;
end;
function TranslatorTypePrimitive.toString(): AnsiString;
begin
case kind of
KIND_VOID:
result := 'void';
KIND_BOOLEAN:
result := 'boolean';
KIND_CHAR:
result := 'char';
KIND_BYTE:
result := 'byte';
KIND_SHORT:
result := 'short';
KIND_INT:
result := 'int';
KIND_LONG:
result := 'long';
KIND_ULTRA:
result := 'ultra';
KIND_FLOAT:
result := 'float';
KIND_DOUBLE:
result := 'double';
KIND_REAL:
result := 'real';
KIND_XVECTOR:
result := 'xvector';
else
result := '';
end;
end;
function TranslatorTypePrimitive.possibleCastTo(typeForTest: TypeDescriptor): boolean;
var
kind: int;
begin
if typeForTest = nil then begin
result := false;
exit;
end;
kind := self.kind;
case typeForTest.kind of
KIND_BOOLEAN:
result := (kind = KIND_BOOLEAN);
KIND_CHAR, KIND_BYTE, KIND_SHORT, KIND_INT, KIND_LONG, KIND_ULTRA,
KIND_FLOAT, KIND_DOUBLE, KIND_REAL, KIND_XVECTOR:
result := (kind = KIND_CHAR) or (kind = KIND_BYTE) or (kind = KIND_SHORT) or
(kind = KIND_INT) or (kind = KIND_LONG) or (kind = KIND_ULTRA) or
(kind = KIND_FLOAT) or (kind = KIND_DOUBLE) or (kind = KIND_REAL) or
(kind = KIND_XVECTOR);
else
result := false;
end;
end;
function TranslatorTypePrimitive.possibleAssignTo(typeForTest: TypeDescriptor): boolean;
var
kind: int;
begin
if typeForTest = nil then begin
result := false;
exit;
end;
kind := self.kind;
case typeForTest.kind of
KIND_BOOLEAN:
result := (kind = KIND_BOOLEAN);
KIND_CHAR:
result := (kind = KIND_CHAR);
KIND_BYTE:
result := (kind = KIND_BYTE);
KIND_SHORT:
result := (kind = KIND_BYTE) or (kind = KIND_SHORT);
KIND_INT:
result := (kind = KIND_CHAR) or (kind = KIND_BYTE) or (kind = KIND_SHORT) or
(kind = KIND_INT);
KIND_LONG:
result := (kind = KIND_CHAR) or (kind = KIND_BYTE) or (kind = KIND_SHORT) or
(kind = KIND_INT) or (kind = KIND_LONG);
KIND_ULTRA:
result := (kind = KIND_CHAR) or (kind = KIND_BYTE) or (kind = KIND_SHORT) or
(kind = KIND_INT) or (kind = KIND_LONG) or (kind = KIND_ULTRA);
KIND_FLOAT:
result := (kind = KIND_CHAR) or (kind = KIND_BYTE) or (kind = KIND_SHORT) or
(kind = KIND_FLOAT);
KIND_DOUBLE:
result := (kind = KIND_CHAR) or (kind = KIND_BYTE) or (kind = KIND_SHORT) or
(kind = KIND_INT) or (kind = KIND_FLOAT) or (kind = KIND_DOUBLE);
KIND_REAL:
result := (kind = KIND_CHAR) or (kind = KIND_BYTE) or (kind = KIND_SHORT) or
(kind = KIND_INT) or (kind = KIND_LONG) or (kind = KIND_FLOAT) or
(kind = KIND_DOUBLE) or (kind = KIND_REAL);
KIND_XVECTOR:
result := (kind = KIND_CHAR) or (kind = KIND_BYTE) or (kind = KIND_SHORT) or
(kind = KIND_FLOAT) or (kind = KIND_XVECTOR);
else
result := false;
end;
end;
function TranslatorTypePrimitive.possibleAssignLong(value: long): boolean;
begin
case kind of
KIND_CHAR:
result := (value >= $0000) and (value <= $ffff);
KIND_BYTE:
result := (value >= -$80) and (value <= $7f);
KIND_SHORT:
result := (value >= -$8000) and (value <= $7fff);
KIND_INT:
result := (value >= -$80000000) and (value <= $7fffffff);
KIND_FLOAT, KIND_XVECTOR:
result := (value >= -$01000000) and (value <= $01000000);
KIND_DOUBLE:
result := (value >= -$0020000000000000) and (value <= $0020000000000000);
KIND_REAL, KIND_LONG, KIND_ULTRA:
result := true;
else
result := false;
end;
end;
{ TranslatorTypeArray }
constructor TranslatorTypeArray.create(operandSize: int; elementType: TypeDescriptor);
var
dimensions: int;
cellType: TypeDescriptor;
begin
inherited create(KIND_ARRAY or (operandSize and $ff));
dimensions := 1;
cellType := elementType;
while cellType is TypeArray do begin
inc(dimensions);
cellType := (cellType as TypeArray).elementType;
end;
self.dimensions := dimensions;
self.cellType := cellType;
self.elementType := elementType;
self.textRepresentation := elementType.toString() + '[]';
end;
function TranslatorTypeArray.equals(obj: TObject): boolean;
begin
result := (obj = self) or (obj is TranslatorTypeArray) and
(TranslatorTypeArray(obj).elementType = elementType);
end;
function TranslatorTypeArray.getHashCode(): int;
begin
result := cellType.getHashCode() xor (1 shl dimensions);
end;
function TranslatorTypeArray.toString(): AnsiString;
begin
result := textRepresentation;
end;
function TranslatorTypeArray.possibleCastTo(typeForTest: TypeDescriptor): boolean;
var
adim: int;
tdim: int;
acel: TypeDescriptor;
tcel: TypeDescriptor;
aarr: TypeArray;
begin
if typeForTest = nil then begin
result := false;
exit;
end;
case typeForTest.kind of
KIND_ARRAY: begin
aarr := typeForTest as TypeArray;
tcel := self.cellType;
acel := aarr.cellType;
tdim := self.dimensions;
adim := aarr.dimensions;
if adim < tdim then begin
result := (acel is TypeStructure) and ((acel as TypeStructure).ancestor = nil);
end else
if adim = tdim then begin
result := (acel <> nil) and (tcel <> nil) and (acel.size = tcel.size) and
(tcel.possibleAssignTo(acel) or acel.possibleAssignTo(tcel));
end else begin
result := false;
end;
end;
KIND_STRUCT: begin
result := (typeForTest as TypeStructure).ancestor = nil;
end;
else
result := false;
end;
end;
function TranslatorTypeArray.possibleAssignTo(typeForTest: TypeDescriptor): boolean;
var
adim: int;
tdim: int;
acel: TypeDescriptor;
tcel: TypeDescriptor;
aarr: TypeArray;
begin
if typeForTest = nil then begin
result := false;
exit;
end;
case typeForTest.kind of
KIND_ARRAY: begin
aarr := typeForTest as TypeArray;
tcel := self.cellType;
acel := aarr.cellType;
tdim := self.dimensions;
adim := aarr.dimensions;
if adim < tdim then begin
result := (acel is TypeStructure) and ((acel as TypeStructure).ancestor = nil);
end else
if adim = tdim then begin
result := (acel <> nil) and (tcel <> nil) and (acel.size = tcel.size) and
tcel.possibleAssignTo(acel);
end else begin
result := false;
end;
end;
KIND_STRUCT: begin
result := (typeForTest as TypeStructure).ancestor = nil;
end;
else
result := false;
end;
end;
function TranslatorTypeArray.getDimensions(): int;
begin
result := dimensions;
end;
function TranslatorTypeArray.getCellType(): TypeDescriptor;
begin
result := cellType;
end;
function TranslatorTypeArray.getElementType(): TypeDescriptor;
begin
result := elementType;
end;
{ TranslatorTypeFunction }
constructor TranslatorTypeFunction.create(operandSize: int; returnType: TypeDescriptor);
begin
inherited create(KIND_FUNC or (operandSize and $ff));
self.argSize := 0;
self.argCount := 0;
self.returnType := returnType;
self.arguments := nil;
end;
function TranslatorTypeFunction.equals(obj: TObject): boolean;
var
i: int;
c: int;
afunc: TranslatorTypeFunction;
aargs: FunctionArgument_Array1d;
targs: FunctionArgument_Array1d;
begin
if obj = self then begin
result := true;
exit;
end;
if not (obj is TranslatorTypeFunction) then begin
result := false;
exit;
end;
afunc := TranslatorTypeFunction(obj);
c := self.argCount;
if (self.returnType <> afunc.returnType) or (c <> afunc.argCount) then begin
result := false;
exit;
end;
aargs := afunc.arguments;
targs := self.arguments;
for i := c - 1 downto 0 do begin
if aargs[i].dataType <> targs[i].dataType then begin
result := false;
exit;
end;
end;
result := true;
end;
function TranslatorTypeFunction.getHashCode(): int;
var
i: int;
c: int;
returnType: TypeDescriptor;
arguments: FunctionArgument_Array1d;
begin
c := self.argCount - 1;
returnType := self.returnType;
arguments := self.arguments;
if returnType <> nil then begin
result := returnType.getHashCode();
end else begin
result := 0;
end;
for i := 0 to c do begin
result := (31 * result) + arguments[i].dataType.getHashCode();
end;
end;
function TranslatorTypeFunction.toString(): AnsiString;
var
i: int;
c: int;
returnType: TypeDescriptor;
arguments: FunctionArgument_Array1d;
begin
c := self.argCount - 1;
returnType := self.returnType;
arguments := self.arguments;
if returnType <> nil then begin
result := returnType.toString();
end else begin
result := '<untyped>';
end;
result := result + '(';
for i := 0 to c do begin
result := result + arguments[i].dataType.toString();
if i < c then begin
result := result + ', ';
end;
end;
result := result + ')';
end;
function TranslatorTypeFunction.possibleCastTo(typeForTest: TypeDescriptor): boolean;
begin
if typeForTest = nil then begin
result := false;
exit;
end;
case typeForTest.kind of
KIND_FUNC: begin
result := equals(typeForTest as TObject);
end;
KIND_STRUCT: begin
result := (typeForTest as TypeStructure).ancestor = nil;
end;
else
result := false;
end;
end;
function TranslatorTypeFunction.possibleAssignTo(typeForTest: TypeDescriptor): boolean;
begin
if typeForTest = nil then begin
result := false;
exit;
end;
case typeForTest.kind of
KIND_FUNC: begin
result := equals(typeForTest as TObject);
end;
KIND_STRUCT: begin
result := (typeForTest as TypeStructure).ancestor = nil;
end;
else
result := false;
end;
end;
function TranslatorTypeFunction.getArgumentsSize(): int;
begin
result := argSize;
end;
function TranslatorTypeFunction.getArgumentsCount(): int;
begin
result := argCount;
end;
function TranslatorTypeFunction.getReturnType(): TypeDescriptor;
begin
result := returnType;
end;
function TranslatorTypeFunction.getArgument(index: int): FunctionArgument;
begin
if (index < 0) or (index >= argCount) then begin
raise IndexOutOfBoundsException.create(msgIndexOutOfBounds);
end;
result := arguments[index];
end;
function TranslatorTypeFunction.findArgument(const argName: UnicodeString): FunctionArgument;
var
i: int;
c: int;
current: FunctionArgument;
arguments: FunctionArgument_Array1d;
begin
c := self.argCount - 1;
arguments := self.arguments;
for i := 0 to c do begin
current := arguments[i];
if current.name = argName then begin
result := current;
exit;
end;
end;
result := nil;
end;
function TranslatorTypeFunction.addArgument(argType: TypeDescriptor;
const argName: UnicodeString): FunctionArgument;
var
c: int;
arguments: FunctionArgument_Array1d;
newarguments: FunctionArgument_Array1d;
begin
if argType = nil then begin
raise NullPointerException.create(msgNullPointer);
end;
c := self.argCount;
arguments := self.arguments;
if length(arguments) = c then begin
newarguments := FunctionArgument_Array1d(Interface_Array1d_create((c shl 1) + 1));
arraycopyInterfaces(arguments, 0, newarguments, 0, c);
self.arguments := newarguments;
arguments := newarguments;
end;
result := TranslatorFunctionArgument.create(argType, argName);
inc(self.argSize, argType.getAlignedSize(kind and $ff));
arguments[c] := result;
self.argCount := c + 1;
end;
{ TranslatorTypeStructure }
constructor TranslatorTypeStructure.create(entryOwner: Namespace; entryPublic: boolean;
const entryName: UnicodeString; operandSize: int; ancestorStructure: TypeStructure);
var
representation: UnicodeString;
begin
inherited create(KIND_STRUCT or (operandSize and $ff));
if (entryOwner <> nil) and (length(entryName) > 0) then begin
representation := entryOwner.name + '.' + entryName;
end else begin
representation := entryName;
end;
self.entryPublic := entryPublic;
self.fldSize := 0;
self.fldCount := 0;
self.startPosition := -1;
self.declarePosition := -1;
self.entryOwner := entryOwner;
self.ancestor := ancestorStructure;
self.fields := nil;
self.entryName := entryName;
self.textRepresentation := stringToUTF8(representation);
end;
function TranslatorTypeStructure.toString(): AnsiString;
begin
result := textRepresentation;
end;
function TranslatorTypeStructure.possibleCastTo(typeForTest: TypeDescriptor): boolean;
var
astr: TypeStructure;
begin
if typeForTest = nil then begin
result := false;
exit;
end;
case typeForTest.kind of
KIND_ARRAY, KIND_FUNC: begin
result := ancestor = nil;
end;
KIND_STRUCT: begin
astr := typeForTest as TypeStructure;
result := astr.isInheritedFrom(self) or self.isInheritedFrom(astr);
end;
else
result := false;
end;
end;
function TranslatorTypeStructure.possibleAssignTo(typeForTest: TypeDescriptor): boolean;
begin
result := (typeForTest <> nil) and (typeForTest is TypeStructure) and
isInheritedFrom(typeForTest as TypeStructure);
end;
procedure TranslatorTypeStructure.clear();
begin
fldSize := 0;
fldCount := 0;
fields := nil;
end;
procedure TranslatorTypeStructure.updateSize();
var
ancestor: TypeStructure;
begin
ancestor := self.ancestor;
if ancestor <> nil then begin
fldSize := ancestor.structureSize;
end;
end;
function TranslatorTypeStructure.isInheritedFrom(ancestorForTest: TypeStructure): boolean;
var
current: TypeStructure;
obj: TObject;
begin
current := self;
obj := ancestorForTest as TObject;
while (current <> nil) and ((current as TObject) <> obj) do begin
current := current.ancestor;
end;
result := (current as TObject) = obj;
end;
function TranslatorTypeStructure.getStructureSize(): int;
begin
result := fldSize;
end;
function TranslatorTypeStructure.getFieldsCount(): int;
begin
result := fldCount;
end;
function TranslatorTypeStructure.getAncestor(): TypeStructure;
begin
result := ancestor;
end;
function TranslatorTypeStructure.getField(index: int): StructureField;
begin
if (index < 0) or (index >= fldCount) then begin
raise IndexOutOfBoundsException.create(msgIndexOutOfBounds);
end;
result := fields[index];
end;
function TranslatorTypeStructure.findField(const fldName: UnicodeString;
findInAncestors: boolean): StructureField;
var
i: int;
c: int;
ancestor: TypeStructure;
current: StructureField;
fields: StructureField_Array1d;
begin
c := self.fldCount - 1;
fields := self.fields;
for i := 0 to c do begin
current := fields[i];
if current.name = fldName then begin
result := current;
exit;
end;
end;
ancestor := self.ancestor;
if findInAncestors and (ancestor <> nil) then begin
result := ancestor.findField(fldName, true);
exit;
end;
result := nil;
end;
function TranslatorTypeStructure.addField(fldPublic: boolean; fldType: TypeDescriptor;
const fldName: UnicodeString): StructureField;
var
c: int;
offset: int;
fields: StructureField_Array1d;
newfields: StructureField_Array1d;
begin
if fldType = nil then begin
raise NullPointerException.create(msgNullPointer);
end;
c := self.fldCount;
offset := self.fldSize;
fields := self.fields;
if length(fields) = c then begin
newfields := StructureField_Array1d(Interface_Array1d_create((c shl 1) + 1));
arraycopyInterfaces(fields, 0, newfields, 0, c);
self.fields := newfields;
fields := newfields;
end;
result := TranslatorStructureField.create(self, offset, fldPublic, fldType, fldName);
self.fldSize := offset + fldType.size;
fields[c] := result;
self.fldCount := c + 1;
end;
procedure TranslatorTypeStructure.setDeclarePosition(declarePosition: int);
begin
self.declarePosition := declarePosition;
end;
procedure TranslatorTypeStructure.setStartPosition(startPosition: int);
begin
self.startPosition := startPosition;
end;
function TranslatorTypeStructure.getDeclarePosition(): int;
begin
result := declarePosition;
end;
function TranslatorTypeStructure.getStartPosition(): int;
begin
result := startPosition;
end;
function TranslatorTypeStructure.getName(): UnicodeString;
begin
result := entryName;
end;
function TranslatorTypeStructure.isPublic(): boolean;
begin
result := entryPublic;
end;
function TranslatorTypeStructure.getOwner(): Namespace;
begin
result := entryOwner;
end;
{ TranslatorNameAndTypeObject }
constructor TranslatorNameAndTypeObject.create(objType: TypeDescriptor;
const objName: UnicodeString);
var
representation: AnsiString;
begin
inherited create();
if objType <> nil then begin
representation := objType.toString();
end else begin
representation := '<untyped>';
end;
self.startPosition := -1;
self.declarePosition := -1;
self.objType := objType;
self.objName := objName;
self.textRepresentation := representation + #$20 + stringToUTF8(objName);
end;
function TranslatorNameAndTypeObject.toString(): AnsiString;
begin
result := textRepresentation;
end;
procedure TranslatorNameAndTypeObject.setDeclarePosition(declarePosition: int);
begin
self.declarePosition := declarePosition;
end;
procedure TranslatorNameAndTypeObject.setStartPosition(startPosition: int);
begin
self.startPosition := startPosition;
end;
function TranslatorNameAndTypeObject.getDeclarePosition(): int;
begin
result := declarePosition;
end;
function TranslatorNameAndTypeObject.getStartPosition(): int;
begin
result := startPosition;
end;
function TranslatorNameAndTypeObject.getName(): UnicodeString;
begin
result := objName;
end;
function TranslatorNameAndTypeObject.getDataType(): TypeDescriptor;
begin
result := objType;
end;
{ TranslatorLocalVariable }
constructor TranslatorLocalVariable.create(varType: TypeDescriptor; const varName: UnicodeString);
begin
inherited create(varType, varName);
end;
{ TranslatorStructureField }
constructor TranslatorStructureField.create(fldOwner: TypeStructure; fldOffset: int;
fldPublic: boolean; fldType: TypeDescriptor; const fldName: UnicodeString);
var
ownedEntry: NamespaceEntry;
ownedNamespace: Namespace;
representation: UnicodeString;
begin
inherited create(fldType, fldName);
if fldOwner is NamespaceEntry then begin
ownedEntry := fldOwner as NamespaceEntry;
ownedNamespace := ownedEntry.owner;
if ownedNamespace <> nil then begin
representation := ownedNamespace.name + '.' + ownedEntry.name + '.' + fldName;
end else begin
representation := ownedEntry.name + '.' + fldName;
end;
end else begin
representation := fldName;
end;
if fldType <> nil then begin
representation := stringToUTF16(fldType.toString() + #$20) + representation;
end else begin
representation := '<untyped> ' + representation;
end;
self.fldPublic := fldPublic;
self.fldOffset := fldOffset;
self.fldOwner := fldOwner;
self.textRepresentation := stringToUTF8(representation);
end;
function TranslatorStructureField.toString(): AnsiString;
begin
result := textRepresentation;
end;
function TranslatorStructureField.isPublic(): boolean;
begin
result := fldPublic;
end;
function TranslatorStructureField.getOffset(): int;
begin
result := fldOffset;
end;
function TranslatorStructureField.getOwner(): TypeStructure;
begin
result := fldOwner;
end;
{ TranslatorFunctionArgument }
constructor TranslatorFunctionArgument.create(argType: TypeDescriptor;
const argName: UnicodeString);
begin
inherited create(argType, argName);
end;
end.