Newer
Older
tac2grc / src / tacsrc / tac.py
@lukas lukas on 14 Aug 2022 4 KB initial commit
from defaultBlockTypes import addDefaultBlockTypes
from tacsrc.block import Block
from tacsrc.blockType import BlockType
from tacsrc.link import Link

import re

def addBlockType(blockTypes, blockType):
    if not BlockType in blockTypes:
        blockTypes[blockTypes] = BlockType(blockType)

def setBlockType(blockIndex, blockTypeName, blocks, blockTypes):
    if not blockTypeName in blockTypes:
        blockTypes[blockTypeName] = BlockType(blockTypeName)
    blocks += [0] * (blockIndex - len(blocks) + 1)
    if blocks[blockIndex] == 0:
        blocks[blockIndex] = Block()
    blocks[blockIndex].blockType = blockTypes[blockTypeName]

def setBlockName(blockIndex, blockName, blocks):
    blocks += [0] * (blockIndex - len(blocks) + 1)
    if blocks[blockIndex] == 0:
        blocks[blockIndex] = Block()
    blocks[blockIndex].name = blockName

def setBlockParameters(blockIndex, blockParameters, blocks):
    blocks += [0] * (blockIndex - len(blocks) + 1)
    if blocks[blockIndex] == 0:
        blocks[blockIndex] = Block()
    blocks[blockIndex].parameters = blockParameters.split(',')

def ensureLinks(linkIndex, links):
    links += [None] * (linkIndex + 1 - len(links))
    if links[linkIndex] == None:
        links[linkIndex] = Link()

def setLinkSourceBlock(linkIndex, sourceBlock, links):
    ensureLinks(linkIndex, links)
    links[linkIndex].fromBlock = sourceBlock

def setLinkSourcePort(linkIndex, sourcePort, links):
    ensureLinks(linkIndex, links)
    links[linkIndex].fromPort = sourcePort

def setLinkDestinationBlock(linkIndex, destinationBlock, links):
    ensureLinks(linkIndex, links)
    links[linkIndex].toBlock = destinationBlock

def setLinkDestinationPort(linkIndex, destinationPort, links):
    ensureLinks(linkIndex, links)
    links[linkIndex].toPort = destinationPort

def readTAC(filename):
    blockTypes = {}
    addDefaultBlockTypes(blockTypes)
    blocks = []
    links = []
    # make sure all blocks have been declared before the links are read
    linkLines = []
    print("reading file %s" % filename)
    with open(filename, "r") as file:
        content = file.readlines()
    for line in content:
        if len(line) == 0:
            continue
        if re.match("TAC\\.LINK.*", line):
            linkLines.append(line)
        if not re.match("TAC\\.BLOCK.*", line):
            continue
        blockIndex = int(re.search("(?<=TAC\\.BLOCK)\\d+", line).group())
        if re.match("TAC\\.BLOCK\\d+\\.TYPE \\w+", line):
            setBlockType(blockIndex, re.search("\\w+$", line).group(), blocks, blockTypes)
        elif re.match("TAC\\.BLOCK\\d+\\.NAME \\w+", line):
            setBlockName(blockIndex, re.search("\\w+$", line).group(), blocks)
        elif re.match("TAC\\.BLOCK\\d+\\.PARAM .+", line):
            setBlockParameters(blockIndex, re.search("(?<=\\.PARAM ).*$", line).group(), blocks)
    blocksByName = {}
    for block in blocks:
        blocksByName[block.name] = block
    for line in linkLines:
        linkIndex = int(re.search("(?<=TAC\\.LINK)\\d+", line).group())
        if   re.match("TAC\\.LINK\\d+\\.SOURCE\\.NAME \\w+", line):
            sourceBlockName = re.search("\\w+$", line).group()
            sourceBlock = blocksByName[sourceBlockName]
            setLinkSourceBlock(linkIndex, sourceBlock, links)
        elif re.match("TAC\\.LINK\\d+\\.SOURCE\\.PORT \\d+", line):
            sourcePort = int(re.search("\\d+$", line).group())
            setLinkSourcePort(linkIndex, sourcePort, links)
        elif re.match("TAC\\.LINK\\d+\\.DEST\\.NAME \\w+", line):
            destinationBlock = blocksByName[re.search("\\w+$", line).group()]
            setLinkDestinationBlock(linkIndex, destinationBlock, links)
        elif re.match("TAC\\.LINK\\d+\\.DEST\\.PORT \\d+", line):
            destinationPort = int(re.search("\\d+$", line).group())
            setLinkDestinationPort(linkIndex, destinationPort, links)
    for link in links:
        link.fromBlock.blockType.outputs.ensureLength(link.fromPort)
        link.toBlock.blockType.inputs.ensureLength(link.toPort)
    return blocks, links, blockTypes.values()