Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions wdl/commands/legacy_drivers.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ def __call__(self, cli_mode: bool) -> int:
global subroutines
subroutines = Parser.get_subroutines(self._text)
Parser.get_params(self._text)
Parser.get_consts(self._text)
output: str = Parser.parse(self._text)

#apparently this one just prints it out, to stdout I guess?
Expand Down
68 changes: 56 additions & 12 deletions wdl/wavgen.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@
Catalog = [] # list of all TimingSegment objects
Parameters = collections.OrderedDict() # all the parameters
Constants = collections.OrderedDict() # all the constants

# bidirectional const name <-> unique placeholder value, so a const used
# as a WAVEFORM "SET ... TO <const>" level survives the numeric state
# and can be swapped back for its name when the ACF is written (see state())
__constLevels__ = {}
__SignalByName__ = {}
__SignalByIndx__ = {}
__seq_ID__ = 0
Expand Down Expand Up @@ -165,13 +170,25 @@ def loadWDL(infile, outfile="/dev/null", verbose=1):
thisTS.sequenceDef.append([ctr, line[:-1]])
ctr += 1
elif TStype == "waveform":
match = re.search(r"(\d+)\s+(\d+)\s+(\d+)\s+([+-]?[\d\.]+)", line)
match = re.search(
r"(\d+)\s+(\d+)\s+(\d+)\s+([+-]?[\d.]+|[A-Za-z_]\w*)", line
)
if match is not None:
# body of a waveform
time = int(match.group(1))
nslot = int(match.group(2))
chan = int(match.group(3)) # this is the slot channel
value = float(match.group(4))
rawlevel = match.group(4)
if re.match(r"^[+-]?[\d.]+$", rawlevel):
value = float(rawlevel)
else:
# a const name used as the SET...TO level: give
# it a unique placeholder (see __constLevels__)
if rawlevel not in __constLevels__:
placeholder = -1.0e18 - len(__constLevels__)
__constLevels__[rawlevel] = placeholder
__constLevels__[placeholder] = rawlevel
value = __constLevels__[rawlevel]
# get the key for the slot
foundBoardType = False
for board_type in slot:
Expand Down Expand Up @@ -1069,6 +1086,13 @@ def state(outfile=None):
global UniqueStateArr
global __chan_per_board__

def levelstr(value, fmt="%g"):
"""format a level value, substituting the const name if this
value is a registered SET...TO placeholder (see __constLevels__)"""
value = float(value)
name = __constLevels__.get(value)
return name if name is not None else fmt % value

if outfile is None:
ofile = sys.stdout
elif type(outfile) is str:
Expand Down Expand Up @@ -1122,8 +1146,8 @@ def state(outfile=None):
)
else:
# in USA, 0==FAST 1==SLOW. IN ACF, 1==FAST, 0==SLOW.
statestring += "%g,%d,0," % (
UniqueStateArr[ii, jj_level],
statestring += "%s,%d,0," % (
levelstr(UniqueStateArr[ii, jj_level]),
int(not bool(UniqueStateArr[ii, jj_fast])),
)

Expand All @@ -1139,7 +1163,9 @@ def state(outfile=None):
if not UniqueStateArr[ii, jj_change]:
statestring += "1,1,"
else:
statestring += "%d,0," % (UniqueStateArr[ii, jj_level])
statestring += "%s,0," % (
levelstr(UniqueStateArr[ii, jj_level], "%d")
)
statestring = statestring[:-1] + '"'
ofile.write(statestring + "\n")
offset += 2 * __chan_per_board__["lvds"]
Expand All @@ -1152,7 +1178,9 @@ def state(outfile=None):
if not UniqueStateArr[ii, jj_change]:
statestring += "1,1,"
else:
statestring += "%d,0," % (UniqueStateArr[ii, jj_level])
statestring += "%s,0," % (
levelstr(UniqueStateArr[ii, jj_level], "%d")
)
statestring = statestring[:-1] + '"'
ofile.write(statestring + "\n")
offset += 2 * __chan_per_board__["htr"]
Expand Down Expand Up @@ -1184,7 +1212,10 @@ def state(outfile=None):
# 2. get the level corresponding to on the non-keep.
pxvbd_chan = np.where(pxvbdKeep == 0)[0]
# again need comma at end of pops string
statestring += "1,%d,%g," % (pxvbd_chan + 1, pxvbdLevel[pxvbd_chan])
statestring += "1,%d,%s," % (
pxvbd_chan + 1,
levelstr(pxvbdLevel[pxvbd_chan]),
)
else:
print(
"Error in positive XVBD state call -- multiple changes "
Expand Down Expand Up @@ -1212,7 +1243,10 @@ def state(outfile=None):
elif (nKeepSum + 1) == (__chan_per_board__["xvbd"] / 2):
# 2. get the level corresponding to on the non-keep.
nxvbd_chan = np.where(nxvbdKeep == 0)[0]
statestring += "1,%d,%g" % (nxvbd_chan + 1, nxvbdLevel[nxvbd_chan])
statestring += "1,%d,%s" % (
nxvbd_chan + 1,
levelstr(nxvbdLevel[nxvbd_chan]),
)
else:
print(
"Error in negative XVBD state call -- multiple changes "
Expand All @@ -1230,7 +1264,9 @@ def state(outfile=None):
if not UniqueStateArr[ii, jj_change]:
statestring += "0,1,"
else:
statestring += "%d,0," % (UniqueStateArr[ii, jj_level])
statestring += "%s,0," % (
levelstr(UniqueStateArr[ii, jj_level], "%d")
)
statestring = statestring[:-1] + '"'
ofile.write(statestring + "\n")
offset += 2
Expand Down Expand Up @@ -1269,7 +1305,10 @@ def state(outfile=None):
elif (KeepSum + 1) == __chan_per_board__["hvbd"]: # proper change
# 2. get the level corresponding to the non-keep.
hvbd_chan = int(np.where(hvbdKeep == 0)[0][0])
statestring += "1,%d,%g" % (hvbd_chan + 1, hvbdLevel[hvbd_chan])
statestring += "1,%d,%s" % (
hvbd_chan + 1,
levelstr(hvbdLevel[hvbd_chan]),
)
else:
print("Error in HVBD state call -- multiple changes in a state")
ofile.write(statestring + '"\n')
Expand All @@ -1294,7 +1333,9 @@ def state(outfile=None):
if not UniqueStateArr[ii, jj_change]:
statestring += "1,1,"
else:
statestring += "%d,0," % (UniqueStateArr[ii, jj_level])
statestring += "%s,0," % (
levelstr(UniqueStateArr[ii, jj_level], "%d")
)

# move back to beginning of voltages
offset -= 2 * (__chan_per_board__["lvbd"] - n_LVDIO)
Expand All @@ -1316,7 +1357,10 @@ def state(outfile=None):
elif (KeepSum + 1) == n_LVBIAS:
# 2. get the level corresponding to the non-keep.
lvbd_chan = np.where(lvbdKeep == 0)[0]
statestring += "1,%d,%g" % (lvbd_chan + 1, lvbdLevel[lvbd_chan])
statestring += "1,%d,%s" % (
lvbd_chan + 1,
levelstr(lvbdLevel[lvbd_chan]),
)
else:
print("Error in LVBD state call -- multiple changes in a state")
ofile.write(statestring + '"\n')
Expand Down
38 changes: 36 additions & 2 deletions wdl/wdlParser.py
Original file line number Diff line number Diff line change
Expand Up @@ -2322,6 +2322,7 @@ def name_label():
def generic_sequence(*sequenceName):
""" """
global token
global constNames
has_exit = False
# sequence/waveform must start with an open (left) curly brace, {
consume("{")
Expand All @@ -2337,6 +2338,7 @@ def generic_sequence(*sequenceName):
(found(IDENTIFIER))
and (token.cargo not in subroutines)
and (token.cargo not in paramNames)
and (token.cargo not in constNames)
):
error(
"(wdlParser.py::generic_sequence) undefined symbol "
Expand Down Expand Up @@ -2371,8 +2373,13 @@ def generic_sequence(*sequenceName):
# it's a number or param
if not found(")"):
sequence_line += "(" + token.cargo # + ")"
# and if it's not a number then it must be a defined param
if not found(NUMBER) and token.cargo not in paramNames:
# and if it's not a number then it must be a defined
# param or const
if (
not found(NUMBER)
and token.cargo not in paramNames
and token.cargo not in constNames
):
error(
"(wdlParser.py::generic_sequence) undefined "
"param " + token.show(align=False)
Expand Down Expand Up @@ -2631,6 +2638,33 @@ def get_params(source_text):
return paramNames


# -----------------------------------------------------------------------------
# @fn get_consts
# @brief
# @param source_text
# @return none
# -----------------------------------------------------------------------------
def get_consts(source_text):
""" """
global token
global constNames

Lexer.initialize(source_text)

while True:
get_token()
if token.type == EOF:
break
if found("const"):
consume("const")
constNames.append(token.cargo)
consume(IDENTIFIER)
consume("=")
consume(NUMBER)

return constNames


# -----------------------------------------------------------------------------
# @fn parse_modules
# @brief creates the .modules file
Expand Down
1 change: 1 addition & 0 deletions wdl/wdlParserDriver.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ def main(input_source_text):
subroutines = Parser.get_subroutines(input_source_text)

Parser.get_params(input_source_text)
Parser.get_consts(input_source_text)

wdl_output = Parser.parse(input_source_text)

Expand Down
Loading