Skip to content

Instantly share code, notes, and snippets.

@tadeokondrak
Last active October 31, 2022 20:00
Show Gist options
  • Select an option

  • Save tadeokondrak/d1615e0a7dde039e7de440287c8eb83e to your computer and use it in GitHub Desktop.

Select an option

Save tadeokondrak/d1615e0a7dde039e7de440287c8eb83e to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
# pc
#
# Copyright (c) 2022 Tadeo Kondrak
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
# FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
# OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# PERFORMANCE OF THIS SOFTWARE.
import sys
from collections import OrderedDict
from typing import Dict, List, Optional, Tuple
from scfg import Config
config = Config(sys.argv[1])
io: Dict[str, List[Tuple[int, str, Optional[int]]]] = {}
circuit_groups: OrderedDict[str, List[Tuple[str, str]]] = OrderedDict()
custom_functions: OrderedDict[str, List[str]] = OrderedDict()
iotypes = [
"inputs",
"outputs",
"relays",
"timers",
"counters",
]
for directive in config.directives:
if directive.name in iotypes:
for child in directive.children:
number, name = int(child.name), child.params[0]
param = int(child.params[1]) if len(child.params) > 1 else None
io.setdefault(directive.name, []).append((number, name, param))
elif directive.name == "function":
program = list(map(lambda child: child.name, directive.children))
custom_functions[directive.params[0]] = program
elif directive.name == "comment":
circuit_groups[directive.params[0]] = []
elif directive.name == "circuits":
circuit_groups[directive.params[0]] = list(
map(
lambda child: (child.name, child.params[0]),
directive.children,
)
)
else:
print(directive)
with open(
sys.argv[1].removesuffix(".txt") + ".PC6",
"w",
newline="\n",
encoding="utf-16",
) as fp:
print("øõTRiLOGI Ver 5.0", file=fp)
for iotype in iotypes:
for number, name, param in io.get(iotype, []):
if param is not None:
print(f"{number},{name} {param}", file=fp)
else:
print(f"{number},{name}", file=fp)
print("~", file=fp)
for name, circuits in circuit_groups.items():
name = name.replace("\n", "þ")
print(f"${name}þ", file=fp)
for lhs, rhs in circuits:
print(f"{lhs}={rhs}", file=fp)
print(file=fp)
print("~END_CIRCUIT~", file=fp)
for i, (name, program) in enumerate(custom_functions.items()):
print("È", file=fp)
proglen = 1
for line in program:
proglen += len(line) + 1
print(f"Fn#{i},{proglen}", file=fp)
for line in program:
print(line, file=fp)
print(file=fp)
print("~END_CUSTFN~", file=fp)
for i, name in enumerate(custom_functions.keys()):
print(f"{i},{name}", file=fp)
print("~END_CUSTFNLABEL~", file=fp)
for i in range(5):
print(f"{i},0,", file=fp)
print("~END_QUICKTAGS~", file=fp)
print("~END_DEFINES~", file=fp)
print("~END_BREAKPOINTS~", file=fp)
print("192.168.1.6:9080", file=fp)
print("~END_LASTIPADDR~", file=fp)
# py-scfg
#
# Copyright (c) 2009, Peter Sanchez <pjs@petersanchez.com>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or
# without modification, are permitted provided that the
# following conditions are met:
#
# * Redistributions of source code must retain the above
# copyright notice, this list of conditions and the
# following disclaimer.
#
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials
# provided with the distribution.
#
# * Neither the name of Peter Sanchez nor the names of its
# contributors may be used to endorse or promote products
# derived from this software without specific prior written
# permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
# TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import shlex
from typing import List, Dict, Optional
def get(directives, name):
for d in directives:
if d.name == name:
return d
def get_all(directives, name):
results = []
for d in directives:
if d.name == name:
results.append(d)
return results
class Directive:
name: str
params: List[str]
children: List["Directive"]
def __init__(self, name, params, children=None):
self.name = name
self.params = params
self.children = children or []
def __str__(self):
return f"{self.name}: {self.params}"
def get(self, name) -> Optional["Directive"]:
return get(self.children, name)
def get_all(self, name) -> List["Directive"]:
return get_all(self.children, name)
class Config:
directives: List["Directive"] = []
def __init__(self, filename):
self.filename = filename
with open(self.filename) as fp:
directives, closing_brace = self.read_block(fp)
self.directives = directives
def read_block(self, fp):
blocks = []
closing_brace = False
for line in fp:
line = line.strip()
if line.startswith("#"):
continue
words = shlex.split(line)
if not len(words):
continue
if len(words) == 1 and line[-1] == "}":
closing_brace = True
break
if words[-1] == "{" and line[-1] == "{":
words = words[:-1]
name = ""
params = words
if len(words) > 0:
name, params = words[0], words[1:]
child_block, child_closing_brace = self.read_block(fp)
if not child_closing_brace:
raise ValueError("Unexpected EOF")
d = Directive(name, params, child_block)
else:
d = Directive(words[0], words[1:])
blocks.append(d)
return blocks, closing_brace
def get(self, name) -> Optional[Directive]:
return get(self.directives, name)
def get_all(self, name) -> List[Directive]:
return get_all(self.directives, name)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment