Platts

From Esolang
Jump to navigation Jump to search

Platts (Programming Language for Arbitrary Two-Tag Systems) was devised in October 2008 by User:Quintopia as a way to add I/O to 2-Tag systems.

Syntax

A valid Platts program has this format: It begins with a number n followed by a newline. Following this are n production rule specifications, each followed by a newline. Everything else is considered to be the initial input to the tag system. The production rules have this syntax:

<symbol><separator/operator><string-to-produce>

<symbol> is any string of ASCII characters. Every <symbol> must be the same length in characters. <string-to-produce> is an arbitrary length string of ASCII characters, including the empty string. <separator/operator> must be one of these three characters:

| Does nothing special
> Toggles output mode on and off in such a way that the strings produced by the production using this operator are not echoed to output.
! Halts the program immediately if this production rule is used. Allows the programmer to define one or more halt characters.

Output Mode

When output mode is on, all strings produced by every production are echoed to output.

Input

When the program is loaded, all occurrences of the string {input} are replaced by an implementation-dependent indicator. Whenever a string containing this indicator is produced during execution, it is replaced by the next single character from user input. Replacement occurs in the logical order: from left to right in the produced string. This special string may be used in the initial input string as well, but may not be used as the <symbol> for a rule. Doing so may or may cause the program to barf and die, produce unexpected results, or simply invalidate the particular rule in which it is used as such, depending on the implementation.

Implicit Production Rule Definitions

The alphabet used by any 2-Tag specified by this language is the entire ASCII alphabet. Any symbols not explicitly assigned production rules in the program listing are implicitly assigned a production of the empty string. This is another way of saying there will be no error if a symbol must be parsed for which there is no production rule specified.

Examples

Hello World:

4
A>
B|Hello World!
H>K
K!
A0B0

Cat:

4
A>
B|{input}
C>0A0B0C0
0!
A0B0C0

Implementation

Python 2

import sys
from collections import defaultdict

class Platts:
    def __init__(self, filename):
        self.output=False
        try:
            with open(filename,"r") as openfile:
                n=int(openfile.next())
                self.rules=defaultdict(lambda:'|')
                self.string=
                for i in range(n):
                    prodrule = openfile.next().strip('\n')
                    goodrule = False
                    self.symbolsize=1
                    for delim in '|>!':
                        if delim in prodrule:
                            if i==0:
                                self.symbolsize=prodrule.find(delim)
                            elif prodrule.find(delim)!=self.symbolsize:
                                continue
                            symbol,delim,prod = prodrule.partition(delim)
                            self.rules[symbol] = delim+prod
                            goodrule = True
                            break
                    if not goodrule:
                        print "Bad production rule (missing delimiter or misplaced delimiter): "+prodrule
                        sys.exit(1)
                for s in openfile.next():
                    self.string+=s
        except IOError:
            print"File '%s' not found."%f
            sys.exit(1)
    
    def produce(self, symbol):
        act,prod = self.rules[symbol][0],self.rules[symbol][1:]
        if act=='!': self.string=
        if '{input}' in prod:
            prod=prod.replace('{input}',sys.stdin.read(1))
        if act=='>': self.output=not self.output
        elif self.output: sys.stdout.write(prod)
        return prod
    
    def cut(self):
        symbol = self.string[:self.symbolsize]
        self.string = self.string[min(self.symbolsize*2,len(self.string)):]
        return symbol
   
    def run(self):
        while len(self.string)>0:
            appstr=self.produce(self.cut())
            self.string+=appstr

if __name__=="__main__":
    if len(sys.argv)<2:
        print "No filename to execute."
    else:
        Platts(sys.argv[1]).run()

See Also

  • Tag system
  • Tag System on Wikipedia (which is a more complete description than is found on this site.)