Commit a03b075b authored by Michael Büsch's avatar Michael Büsch

Add basic support for arrays in interface

Signed-off-by: Michael Büsch's avatarMichael Buesch <[email protected]>
parent 449f5c89
......@@ -184,13 +184,10 @@ class BlockInterface(object):
raise AwlSimError("Data structure field '%s' does not exist." %\
name)
def getOperatorForFieldName(self, name, wantPointer):
return self.getOperatorForField(self.getFieldByName(name),
wantPointer)
# Get an AwlOperator for TEMP access.
def __getOperatorForField_TEMP(self, interfaceField, wantPointer):
structField = self.tempStruct.getField(interfaceField.name)
def __getOperatorForField_TEMP(self, interfaceField, arrayIndex, wantPointer):
structField = self.tempStruct.getField(interfaceField.name,
arrayIndex)
if wantPointer:
ptrValue = structField.offset.toPointerValue()
return AwlOperator(type = AwlOperator.IMM_PTR,
......@@ -201,16 +198,29 @@ class BlockInterface(object):
width=structField.bitSize,
value=structField.offset.dup())
# Get an AwlOperator that addresses the specified interfaceField.
# Get an AwlOperator that addresses the specified interface field identified
# by "name" and "indices".
# "name" is the field name and "indices" are the array indices, if any.
# If wantPointer is true, an IMM_PTR AwlOperator to the interfaceField
# is returned.
def getOperatorForField(self, interfaceField, wantPointer):
def getOperatorForField(self, name, indices, wantPointer):
interfaceField = self.getFieldByName(name)
if interfaceField.dataType.type == AwlDataType.TYPE_ARRAY:
# Get the linear array index.
arrayIndex = interfaceField.dataType.arrayIndicesCollapse(*indices)
else:
arrayIndex = None
if interfaceField.fieldType == interfaceField.FTYPE_TEMP:
# get TEMP interface field operator
return self.__getOperatorForField_TEMP(interfaceField, wantPointer)
return self.__getOperatorForField_TEMP(interfaceField,
arrayIndex,
wantPointer)
# otherwise get IN/OUT/INOUT/STAT interface field operator
structField = self.struct.getField(interfaceField.name)
structField = self.struct.getField(interfaceField.name,
arrayIndex)
# FC-parameters cannot be resolved statically.
assert(self.hasInstanceDB)
......
......@@ -2,7 +2,7 @@
#
# AWL simulator - CPU
#
# Copyright 2012-2013 Michael Buesch <[email protected]>
# Copyright 2012-2014 Michael Buesch <[email protected]>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
......@@ -210,12 +210,11 @@ class S7CPU(object):
def __initDBField(self, db, dataType, rawDataInit):
if dataType.type == AwlDataType.TYPE_ARRAY:
index = dataType.arrayIndicesCollapse(*rawDataInit.idents[-1].indices)
value = dataType.parseMatchingImmediate(rawDataInit.valueTokens)
name = AwlStruct.makeArrayChildName(rawDataInit.idents[-1].name, index)
db.structInstance.setFieldDataByName(name, value)
else:
value = dataType.parseMatchingImmediate(rawDataInit.valueTokens)
db.structInstance.setFieldDataByName(rawDataInit.idents[-1].name, value)
index = None
value = dataType.parseMatchingImmediate(rawDataInit.valueTokens)
db.structInstance.setFieldDataByName(rawDataInit.idents[-1].name,
index, value)
def __translateGlobalDB(self, rawDB):
db = DB(rawDB.index, None)
......@@ -286,10 +285,10 @@ class S7CPU(object):
# Translate classic symbols ("abc")
def __resolveClassicSym(self, block, insn, oper):
if oper.type == AwlOperator.SYMBOLIC:
symbol = self.symbolTable.findByName(oper.value)
symbol = self.symbolTable.findByName(oper.value.varName)
if not symbol:
raise AwlSimError("Symbol \"%s\" not found in "
"symbol table." % oper.value,
"symbol table." % oper.value.varName,
insn = insn)
oper = symbol.operator
return oper
......@@ -318,19 +317,36 @@ class S7CPU(object):
if oper.type != AwlOperator.NAMED_LOCAL:
return oper
field = block.interface.getFieldByName(oper.value)
# Get the interface field for this variable
field = block.interface.getFieldByName(oper.value.varName)
# Sanity checks
if field.dataType.type == AwlDataType.TYPE_ARRAY:
if not oper.value.indices:
raise AwlSimError("Cannot address array #%s "
"without subscript list." %\
oper.value.varName)
else:
if oper.value.indices:
raise AwlSimError("Trying to subscript array, "
"but #%s is not an array." %\
oper.value.varName)
if block.interface.hasInstanceDB or\
field.fieldType == BlockInterfaceField.FTYPE_TEMP:
# This is an FB or a TEMP access. Translate the operator
# to a DI/TEMP access.
newOper = block.interface.getOperatorForFieldName(oper.value, pointer)
newOper = block.interface.getOperatorForField(oper.value.varName,
oper.value.indices,
pointer)
newOper.setInsn(oper.insn)
return newOper
else:
# This is an FC. Accesses to local symbols
# are resolved at runtime.
# Just set the value to the interface index.
index = block.interface.getFieldIndex(oper.value)
#TODO array
index = block.interface.getFieldIndex(oper.value.varName)
oper.interfaceIndex = index
return oper
......@@ -364,7 +380,14 @@ class S7CPU(object):
# Get the data structure field descriptor
# and construct the AwlOffset.
field = db.struct.getField(oper.value.varName)
if oper.value.indices is not None:
if oper.value.indices is None:
# Non-array access.
if field.dataType.type == AwlDataType.TYPE_ARRAY:
#TODO this happens for parameter passing
raise AwlSimError("Variable '%s' in fully qualified "
"DB access is an ARRAY." %\
oper.value.varName)
else:
# This is an array access.
if field.dataType.type != AwlDataType.TYPE_ARRAY:
raise AwlSimError("Indexed variable '%s' in fully qualified "
......@@ -372,8 +395,7 @@ class S7CPU(object):
oper.value.varName)
index = field.dataType.arrayIndicesCollapse(*oper.value.indices)
# Get the actual data field
name = AwlStruct.makeArrayChildName(oper.value.varName, index)
field = db.struct.getField(name)
field = db.struct.getField(oper.value.varName, index)
# Extract the offset data
offset = field.offset.dup()
width = field.bitSize
......
......@@ -125,7 +125,9 @@ class AwlStruct(object):
alignment = 2
self.addFieldAligned(name, dataType, alignment)
def getField(self, name):
def getField(self, name, arrayIndex=None):
if arrayIndex is not None:
name = self.makeArrayChildName(name, arrayIndex)
try:
return self.name2field[name]
except KeyError:
......@@ -151,8 +153,8 @@ class AwlStructInstance(object):
def setFieldData(self, field, value):
self.dataBytes.store(field.offset, field.bitSize, value)
def getFieldDataByName(self, name):
return self.getFieldData(self.struct.getField(name))
def getFieldDataByName(self, name, arrayIndex=None):
return self.getFieldData(self.struct.getField(name, arrayIndex))
def setFieldDataByName(self, name, value):
self.setFieldData(self.struct.getField(name), value)
def setFieldDataByName(self, name, arrayIndex, value):
self.setFieldData(self.struct.getField(name, arrayIndex), value)
......@@ -337,11 +337,11 @@ class AwlOperator(DynAttrs):
elif self.type == self.BLKREF_VAT:
return "VAT %d" % self.value.byteOffset
elif self.type == self.SYMBOLIC:
return '"%s"' % self.value
return '"%s"' % self.value.varName
elif self.type == self.NAMED_LOCAL:
return "#%s" % self.value
return "#%s" % self.value.varName
elif self.type == self.NAMED_LOCAL_PTR:
return "P##%s" % self.value
return "P##%s" % self.value.varName
elif self.type == self.NAMED_DBVAR:
return str(self.value) # value is AwlOffset
elif self.type == self.INDIRECT:
......
......@@ -364,6 +364,25 @@ class AwlOpTranslator(object):
else:
assert(0)
# Translate array indices.
# The first token is the opening brace '['.
# Returns tuple: (list_of_indices, consumed_tokens_count)
def __translateArrayIndices(self, tokens):
indices = []
count = 1
try:
while tokens[count] != ']':
indices.append(int(tokens[count]))
count += 1
if count < len(tokens) and tokens[count] == ',':
count += 1
count += 1 # closing braces
except (ValueError, IndexError) as e:
raise AwlSimError("Invalid array index")
if len(indices) < 1 or len(indices) > 6:
raise AwlSimError("Invalid number of array indices")
return (indices, count)
def __doTrans(self, rawInsn, rawOps):
if rawInsn and rawInsn.block.hasLabel(rawOps[0]):
# Label reference
......@@ -392,16 +411,27 @@ class AwlOpTranslator(object):
return opDesc
# Local variable
if token0.startswith('#'):
offset = AwlOffset(None, None)
offset.varName = rawOps[0][1:]
count = 1
if len(rawOps) >= 4 and rawOps[1] == '[':
# This is an array variable
offset.indices, cnt = self.__translateArrayIndices(rawOps[1:])
count += cnt
return OpDescriptor(AwlOperator(AwlOperator.NAMED_LOCAL, 0,
rawOps[0][1:]), 1)
offset), count)
# Pointer to local variable
if token0.startswith("P##"):
offset = AwlOffset(None, None)
offset.varName = rawOps[0][3:]
return OpDescriptor(AwlOperator(AwlOperator.NAMED_LOCAL_PTR, 0,
rawOps[0][3:]), 1)
offset), 1)
# Symbolic name
if token0.startswith('"') and token0.endswith('"'):
offset = AwlOffset(None, None)
offset.varName = rawOps[0][1:-1]
return OpDescriptor(AwlOperator(AwlOperator.SYMBOLIC, 0,
rawOps[0][1:-1]), 1)
offset), 1)
# Immediate boolean
immediate = AwlDataType.tryParseImmediate_BOOL(rawOps[0])
if immediate is not None:
......@@ -514,27 +544,13 @@ class AwlOpTranslator(object):
else:
offset.dbName = db[1:-1]
offset.varName = match.group(2)
count = 1
if len(rawOps) >= 4 and rawOps[1] == '[':
# DBx.ARRAY[x, y, z] adressing
offset.indices = []
count = 2
try:
while rawOps[count] != ']':
offset.indices.append(int(rawOps[count]))
count += 1
if count < len(rawOps) and rawOps[count] == ',':
count += 1
count += 1 # closing braces
except (ValueError, IndexError) as e:
raise AwlSimError("Invalid array index")
if len(offset.indices) < 1 or len(offset.indices) > 6:
raise AwlSimError("Invalid number of array indices")
return OpDescriptor(AwlOperator(AwlOperator.NAMED_DBVAR, 0,
offset), count)
else:
# DBx.VARIABLE adressing
return OpDescriptor(AwlOperator(AwlOperator.NAMED_DBVAR, 0,
offset), 1)
offset.indices, cnt = self.__translateArrayIndices(rawOps[1:])
count += cnt
return OpDescriptor(AwlOperator(AwlOperator.NAMED_DBVAR, 0,
offset), count)
raise AwlSimError("Cannot parse operand: " +\
str(rawOps[0]))
......
......@@ -88,8 +88,10 @@ class SystemBlock(Block):
self.__interfaceOpers = {}
for field in self.interface.fields_IN_OUT_INOUT_STAT:
# Create a scratch-operator for the access.
offset = AwlOffset(None, None)
offset.varName = field.name
oper = AwlOperator(AwlOperator.NAMED_LOCAL, 0,
field.name)
offset)
# Resolve the scratch-operator.
oper = self.cpu.resolveNamedLocal(block=self, insn=None,
oper=oper, pointer=False)
......
DATA_BLOCK DB 99
TITLE = Main data block
VERSION : 0.1
STRUCT
VAR0 : ARRAY [1 .. 2] OF INT;
VAR1 : ARRAY [1 .. 2] OF INT := 1, 2;
VAR2 : ARRAY [1 .. 2, 1 .. 2] OF INT := 1, 2, 3, 4;
VAR3 : ARRAY [-2 .. -1] OF INT := -2, -1;
VAR4 : ARRAY [1 .. 2, 1 .. 2, 1 .. 2, 1 .. 2, 1 .. 2, 1 .. 2] OF INT := 4 (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
VAR5 : ARRAY [0 .. 9 ] OF INT := 5 (1, 2);
VAR6 : ARRAY [1 .. 2, 1 .. 10, 1 .. 5 ] OF INT := 5 (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20);
VAR7 : ARRAY [1 .. 14 ] OF BOOL := 7 (TRUE, FALSE);
VAR8 : ARRAY [1 .. 3 ] OF BOOL := TRUE, FALSE, TRUE;
VAR9 : ARRAY [1 .. 1 ] OF INT := 42;
// VAR10 : STRUCT
// VAR10_1 : INT := 101;
// VAR10_2 : ARRAY [1 .. 2 ] OF INT := 1, 2;
// VAR10_3 : ARRAY [1 .. 2 ] OF STRUCT
// VAR10_3_1 : INT := 1031;
// VAR10_3_2 : ARRAY [1 .. 2 ] OF INT := 1, 2;
// END_STRUCT;
// END_STRUCT;
END_STRUCT;
BEGIN
VAR0[1] := 0;
VAR0[2] := 0;
VAR1[1] := -30000;
VAR1[2] := 30000;
VAR2[1, 1] := 1;
VAR2[1, 2] := 2;
VAR2[2, 1] := 3;
VAR2[2, 2] := 4;
VAR3[-2] := -2;
VAR3[-1] := -1;
VAR4[1, 1, 1, 1, 1, 1] := 1;
VAR4[1, 1, 1, 1, 1, 2] := 2;
VAR4[1, 1, 1, 1, 2, 1] := 3;
VAR4[1, 1, 1, 1, 2, 2] := 4;
VAR4[1, 1, 1, 2, 1, 1] := 5;
VAR4[1, 1, 1, 2, 1, 2] := 6;
VAR4[1, 1, 1, 2, 2, 1] := 7;
VAR4[1, 1, 1, 2, 2, 2] := 8;
VAR4[1, 1, 2, 1, 1, 1] := 9;
VAR4[1, 1, 2, 1, 1, 2] := 10;
VAR4[1, 1, 2, 1, 2, 1] := 11;
VAR4[1, 1, 2, 1, 2, 2] := 12;
VAR4[1, 1, 2, 2, 1, 1] := 13;
VAR4[1, 1, 2, 2, 1, 2] := 14;
VAR4[1, 1, 2, 2, 2, 1] := 15;
VAR4[1, 1, 2, 2, 2, 2] := 16;
VAR4[1, 2, 1, 1, 1, 1] := 1;
VAR4[1, 2, 1, 1, 1, 2] := 2;
VAR4[1, 2, 1, 1, 2, 1] := 3;
VAR4[1, 2, 1, 1, 2, 2] := 4;
VAR4[1, 2, 1, 2, 1, 1] := 5;
VAR4[1, 2, 1, 2, 1, 2] := 6;
VAR4[1, 2, 1, 2, 2, 1] := 7;
VAR4[1, 2, 1, 2, 2, 2] := 8;
VAR4[1, 2, 2, 1, 1, 1] := 9;
VAR4[1, 2, 2, 1, 1, 2] := 10;
VAR4[1, 2, 2, 1, 2, 1] := 11;
VAR4[1, 2, 2, 1, 2, 2] := 12;
VAR4[1, 2, 2, 2, 1, 1] := 13;
VAR4[1, 2, 2, 2, 1, 2] := 14;
VAR4[1, 2, 2, 2, 2, 1] := 15;
VAR4[1, 2, 2, 2, 2, 2] := 16;
VAR4[2, 1, 1, 1, 1, 1] := 1;
VAR4[2, 1, 1, 1, 1, 2] := 2;
VAR4[2, 1, 1, 1, 2, 1] := 3;
VAR4[2, 1, 1, 1, 2, 2] := 4;
VAR4[2, 1, 1, 2, 1, 1] := 5;
VAR4[2, 1, 1, 2, 1, 2] := 6;
VAR4[2, 1, 1, 2, 2, 1] := 7;
VAR4[2, 1, 1, 2, 2, 2] := 8;
VAR4[2, 1, 2, 1, 1, 1] := 9;
VAR4[2, 1, 2, 1, 1, 2] := 10;
VAR4[2, 1, 2, 1, 2, 1] := 11;
VAR4[2, 1, 2, 1, 2, 2] := 12;
VAR4[2, 1, 2, 2, 1, 1] := 13;
VAR4[2, 1, 2, 2, 1, 2] := 14;
VAR4[2, 1, 2, 2, 2, 1] := 15;
VAR4[2, 1, 2, 2, 2, 2] := 16;
VAR4[2, 2, 1, 1, 1, 1] := 1;
VAR4[2, 2, 1, 1, 1, 2] := 2;
VAR4[2, 2, 1, 1, 2, 1] := 3;
VAR4[2, 2, 1, 1, 2, 2] := 4;
VAR4[2, 2, 1, 2, 1, 1] := 5;
VAR4[2, 2, 1, 2, 1, 2] := 6;
VAR4[2, 2, 1, 2, 2, 1] := 7;
VAR4[2, 2, 1, 2, 2, 2] := 8;
VAR4[2, 2, 2, 1, 1, 1] := 9;
VAR4[2, 2, 2, 1, 1, 2] := 10;
VAR4[2, 2, 2, 1, 2, 1] := 11;
VAR4[2, 2, 2, 1, 2, 2] := 12;
VAR4[2, 2, 2, 2, 1, 1] := 13;
VAR4[2, 2, 2, 2, 1, 2] := 14;
VAR4[2, 2, 2, 2, 2, 1] := 15;
VAR4[2, 2, 2, 2, 2, 2] := 16;
VAR5[0] := 1;
VAR5[1] := 2;
VAR5[2] := 1;
VAR5[3] := 2;
VAR5[4] := 1;
VAR5[5] := 2;
VAR5[6] := 1;
VAR5[7] := 2;
VAR5[8] := 1;
VAR5[9] := 2;
VAR6[1, 1, 1] := 1;
VAR6[1, 1, 2] := 2;
VAR6[1, 1, 3] := 3;
VAR6[1, 1, 4] := 4;
VAR6[1, 1, 5] := 5;
VAR6[1, 2, 1] := 6;
VAR6[1, 2, 2] := 7;
VAR6[1, 2, 3] := 8;
VAR6[1, 2, 4] := 9;
VAR6[1, 2, 5] := 10;
VAR6[1, 3, 1] := 11;
VAR6[1, 3, 2] := 12;
VAR6[1, 3, 3] := 13;
VAR6[1, 3, 4] := 14;
VAR6[1, 3, 5] := 15;
VAR6[1, 4, 1] := 16;
VAR6[1, 4, 2] := 17;
VAR6[1, 4, 3] := 18;
VAR6[1, 4, 4] := 19;
VAR6[1, 4, 5] := 20;
VAR6[1, 5, 1] := 1;
VAR6[1, 5, 2] := 2;
VAR6[1, 5, 3] := 3;
VAR6[1, 5, 4] := 4;
VAR6[1, 5, 5] := 5;
VAR6[1, 6, 1] := 6;
VAR6[1, 6, 2] := 7;
VAR6[1, 6, 3] := 8;
VAR6[1, 6, 4] := 9;
VAR6[1, 6, 5] := 10;
VAR6[1, 7, 1] := 11;
VAR6[1, 7, 2] := 12;
VAR6[1, 7, 3] := 13;
VAR6[1, 7, 4] := 14;
VAR6[1, 7, 5] := 15;
VAR6[1, 8, 1] := 16;
VAR6[1, 8, 2] := 17;
VAR6[1, 8, 3] := 18;
VAR6[1, 8, 4] := 19;
VAR6[1, 8, 5] := 20;
VAR6[1, 9, 1] := 1;
VAR6[1, 9, 2] := 2;
VAR6[1, 9, 3] := 3;
VAR6[1, 9, 4] := 4;
VAR6[1, 9, 5] := 5;
VAR6[1, 10, 1] := 6;
VAR6[1, 10, 2] := 7;
VAR6[1, 10, 3] := 8;
VAR6[1, 10, 4] := 9;
VAR6[1, 10, 5] := 10;
VAR6[2, 1, 1] := 11;
VAR6[2, 1, 2] := 12;
VAR6[2, 1, 3] := 13;
VAR6[2, 1, 4] := 14;
VAR6[2, 1, 5] := 15;
VAR6[2, 2, 1] := 16;
VAR6[2, 2, 2] := 17;
VAR6[2, 2, 3] := 18;
VAR6[2, 2, 4] := 19;
VAR6[2, 2, 5] := 20;
VAR6[2, 3, 1] := 1;
VAR6[2, 3, 2] := 2;
VAR6[2, 3, 3] := 3;
VAR6[2, 3, 4] := 4;
VAR6[2, 3, 5] := 5;
VAR6[2, 4, 1] := 6;
VAR6[2, 4, 2] := 7;
VAR6[2, 4, 3] := 8;
VAR6[2, 4, 4] := 9;
VAR6[2, 4, 5] := 10;
VAR6[2, 5, 1] := 11;
VAR6[2, 5, 2] := 12;
VAR6[2, 5, 3] := 13;
VAR6[2, 5, 4] := 14;
VAR6[2, 5, 5] := 15;
VAR6[2, 6, 1] := 16;
VAR6[2, 6, 2] := 17;
VAR6[2, 6, 3] := 18;
VAR6[2, 6, 4] := 19;
VAR6[2, 6, 5] := 20;
VAR6[2, 7, 1] := 1;
VAR6[2, 7, 2] := 2;
VAR6[2, 7, 3] := 3;
VAR6[2, 7, 4] := 4;
VAR6[2, 7, 5] := 5;
VAR6[2, 8, 1] := 6;
VAR6[2, 8, 2] := 7;
VAR6[2, 8, 3] := 8;
VAR6[2, 8, 4] := 9;
VAR6[2, 8, 5] := 10;
VAR6[2, 9, 1] := 11;
VAR6[2, 9, 2] := 12;
VAR6[2, 9, 3] := 13;
VAR6[2, 9, 4] := 14;
VAR6[2, 9, 5] := 15;
VAR6[2, 10, 1] := 16;
VAR6[2, 10, 2] := 17;
VAR6[2, 10, 3] := 18;
VAR6[2, 10, 4] := 19;
VAR6[2, 10, 5] := 20;
VAR7[1] := TRUE;
VAR7[2] := FALSE;
VAR7[3] := TRUE;
VAR7[4] := FALSE;
VAR7[5] := TRUE;
VAR7[6] := FALSE;
VAR7[7] := TRUE;
VAR7[8] := FALSE;
VAR7[9] := TRUE;
VAR7[10] := FALSE;
VAR7[11] := TRUE;
VAR7[12] := FALSE;
VAR7[13] := TRUE;
VAR7[14] := FALSE;
VAR8[1] := TRUE;
VAR8[2] := FALSE;
VAR8[3] := TRUE;
VAR9[1] := 42;
// VAR10.VAR10_1 := 101;
// VAR10.VAR10_2[1] := 1;
// VAR10.VAR10_2[2] := 2;
// VAR10.VAR10_3[1].VAR10_3_1 := 1031;
// VAR10.VAR10_3[1].VAR10_3_2[1] := 1;
// VAR10.VAR10_3[1].VAR10_3_2[2] := 2;
// VAR10.VAR10_3[2].VAR10_3_1 := 1031;
// VAR10.VAR10_3[2].VAR10_3_2[1] := 1;
// VAR10.VAR10_3[2].VAR10_3_2[2] := 2;
END_DATA_BLOCK
FUNCTION_BLOCK FB 1
VAR_INPUT
VAR0 : ARRAY [1 .. 2] OF INT;
VAR1 : ARRAY [1 .. 2, 0 .. 1] OF INT;
SELECT : INT;
END_VAR
BEGIN
L #SELECT
SPL ERR
SPA M000
SPA M001
ERR: __ASSERT== 1, 2 // Wrong #SELECT
// Check instance-DB initial values
M000: L #VAR0[1]
__ASSERT== __ACCU 1, 1
L DIW 0
__ASSERT== __ACCU 1, 1
L #VAR0[2]
__ASSERT== __ACCU 1, 2
L DIW 2
__ASSERT== __ACCU 1, 2
L #VAR1[1, 0]
__ASSERT== __ACCU 1, 100
L DIW 4
__ASSERT== __ACCU 1, 100
L #VAR1[1, 1]
__ASSERT== __ACCU 1, 101
L DIW 6
__ASSERT== __ACCU 1, 101
L #VAR1[2, 0]
__ASSERT== __ACCU 1, 102
L DIW 8
__ASSERT== __ACCU 1, 102
L #VAR1[2, 1]
__ASSERT== __ACCU 1, 103
L DIW 10
__ASSERT== __ACCU 1, 103
BEA
// Check passed parameters
M001: L #VAR0[1]
__ASSERT== __ACCU 1, 91
L DIW 0
__ASSERT== __ACCU 1, 91
L #VAR0[2]
__ASSERT== __ACCU 1, 92
L DIW 2
__ASSERT== __ACCU 1, 92
L #VAR1[1, 0]
__ASSERT== __ACCU 1, 9100
L DIW 4
__ASSERT== __ACCU 1, 9100
L #VAR1[1, 1]
__ASSERT== __ACCU 1, 9101
L DIW 6
__ASSERT== __ACCU 1, 9101
L #VAR1[2, 0]
__ASSERT== __ACCU 1, 9102
L DIW 8
__ASSERT== __ACCU 1, 9102
L #VAR1[2, 1]
__ASSERT== __ACCU 1, 9103
L DIW 10
__ASSERT== __ACCU 1, 9103
BEA
END_FUNCTION_BLOCK
DATA_BLOCK DB 1
TITLE = FB 1 instance DB
FB 1
BEGIN
VAR0[1] := 1;
VAR0[2] := 2;
VAR1[1, 0] := 100;
VAR1[1, 1] := 101;
VAR1[2, 0] := 102;
VAR1[2, 1] := 103;
SELECT := 0;
END_DATA_BLOCK
DATA_BLOCK DB 2
TITLE = FB 1 parameter passing DB
STRUCT
VAR0 : ARRAY [1 .. 2] OF INT;
VAR1 : ARRAY [1 .. 2, 0 .. 1] OF INT;
END_STRUCT
BEGIN
VAR0[1] := 91;
VAR0[2] := 92;
VAR1[1, 0] := 9100;
VAR1[1, 1] := 9101;
VAR1[2, 0] := 9102;
VAR1[2, 1] := 9103;
END_DATA_BLOCK
ORGANIZATION_BLOCK OB 1
BEGIN
// Check DB99 initial values
L DB99.VAR0[1]
__ASSERT== __ACCU 1, 0
L DB99.DBW 0
__ASSERT== __ACCU 1, 0
L DB99.VAR0[2]
__ASSERT== __ACCU 1, 0
L DB99.DBW 2
__ASSERT== __ACCU 1, 0
L DB99.VAR1[1]
__ASSERT== __ACCU 1, -30000
L DB99.DBW 4
__ASSERT== __ACCU 1, -30000
L DB99.VAR1[2]
__ASSERT== __ACCU 1, 30000
L DB99.DBW 6
__ASSERT== __ACCU 1, 30000
L DB99.VAR2[1, 1]
__ASSERT== __ACCU 1, 1
L DB99.DBW 8
__ASSERT== __ACCU 1, 1
L DB99.VAR2[1, 2]
__ASSERT== __ACCU 1, 2
L DB99.DBW 10
__ASSERT== __ACCU 1, 2
L DB99.VAR2[2, 1]
__ASSERT== __ACCU 1, 3
L DB99.DBW 12
__ASSERT== __ACCU 1, 3
L DB99.VAR2[2, 2]
__ASSERT== __ACCU 1, 4
L DB99.DBW 14
__ASSERT== __ACCU 1, 4
// Call FB 1 without array parameter passing
CALL FB 1, DB 1 (
SELECT := 0,
)
// Call FB 1 with array parameter passing
//TODO CALL FB 1, DB 1 (
// VAR0 := DB2.VAR0,
// VAR1 := DB2.VAR1,
// SELECT := 1,
// )
//TODO FC-tests
END_ORGANIZATION_BLOCK
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment