Commits

Cat's Eye Technologies  committed 632709e

Initial import of Squishy2K 2000.1006 sources.

  • Participants
  • Tags rel_1_0_2000_1006

Comments (0)

Files changed (6)

File doc/license.txt

+Copyright (c)2000, Cat's Eye Technologies.
+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 Cat's Eye Technologies 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 REGENTS 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. 

File doc/squishy2k.txt

+     Subject: [Esoteric] [Languages] New! Squishy2K (v2000.10.06)
+        Date: Fri, 06 Oct 2000 20:56:43 -0500
+        From: Chris Pressey
+Organization: Cat's Eye Technologies
+          To: Cat's Eye Technologies Mailing List
+
+
+Back in ancient history I came up with a language which worked like a
+Turing-Complete EBNF - a compiler-compiler that could also do banal
+computation via translation.  I wanted to call the language Wirth in
+honour of the inventor of EBNF.  But the name SQUISHY was proposed and
+stuck.
+
+SQUISHY is now left to the sands of time, and this was long before I had
+ever heard of a semi-Thue grammar or the language Thue.
+
+But SQUISHY is now back, refurbished for the twenty-first century, in
+the form of Squishy2K!  Squishy2K is a lot like the original SQUISHY
+except with more and less.  It's not as much like EBNF anymore.  On the
+other hand, it's more like a state machine now!  And in Perl it's dead
+simple, something like 7K of code.
+
+Squishy2K is a string-rewriting language (read: Thue) embedded within a
+state machine (read: beta-Juliet) with states-doubling-as-functions
+thrown in for good measure (read: I haven't rhe foggiest idea what I'm
+doing.)
+
+Reading the grammar will prove to you how simple it is.
+
+  Program ::= {State}.
+  State   ::= "*" Name "{" {Rule} ["!" Name] "}".
+  Rule    ::= LString "?" RString "!" [Name].
+  LString ::= {quoted | "few" | "many" | "start" | "finish"}.
+  RString ::= {quoted | digit | Name "(" RString ")"}.
+
+In English... a program consists of any number of states.  Each state
+begins with an asterisk, gives a name (alphanumeric), and contains any
+number of rules and an optional notwithstanding clause between curly
+braces.  The state named "main" is where flow control begins and ends.
+
+Each rule is composed of an "lstring" (a pattern to be searched for) and
+an "rstring" (an expression to replace any matched pattern with.)  The
+pattern tokens "start" and "finish" match the beginning and the end of
+the input string respectively.  The tokens "few" and "many" match any
+number of characters, the former preferring to match as few as possible,
+the latter is "greedy."  In the rstring, backreferences to the few and
+many tokens may be made with digits: 1 indicates the first few or many,
+2 the second, and so on.
+
+Each rule, and the notwithstanding clause, can name another state, and
+when a match succeeds on that rule (or no match succeeds for the
+notwithstanding clause), a transition along the arc to that state fires
+(i.e. it's a goto...)
+
+That's about it.
+
+Now I have to write a fake infomercial for it, and it'll be complete. 
+:-)
+
+_chris
+
+-- 
+Uryc! V'z genccrq vafvqr gur ebg13 plcure!
+Share and Enjoy on Cat's Eye Technologies' Electronic Mailing List
+http://www.catseye.mb.ca/list.html

File eg/format.sq2k

+* main
+{
+  start many "[" few "]"? 1 " open bracket " 2 " close bracket "! main
+  start many "(" few ")"? 1 " open paren " 2 " close paren "! main
+  start many "{" few "}"? 1 " open brace " 2 " close brace "! main
+}

File eg/hello.sq2k

+* main { start many finish? "Hello, world!"! }
+* main
+{
+  "NOT(" few ")"? rewrite(1)! main
+}
+
+* rewrite
+{
+  "0"? "1"!
+  "1"? "0"!
+}

File src/squishy2k.pl

+#!/usr/bin/env perl
+# squishy2k.pl - v2000.10.06 Chris Pressey
+# Squishy2K to Perl 5 compiler in Perl 5
+
+# Copyright (c)2000, Cat's Eye Technologies.
+# 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 Cat's Eye Technologies 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 REGENTS 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. 
+
+### SYNOPSIS
+
+# squishy2k.pl - Squishy2K to Perl 5 compiler in Perl 5
+# usage: [perl] squishy2k[.pl] <input.sq2k >output.pl
+
+### GLOBALS
+
+$token = '';
+$line = '';
+$curline = '';
+
+### SCANNER
+
+sub perr
+{
+  my $msg = shift;
+  print "$msg\n";
+  print "($curline:$token)\n";
+}
+
+sub scan
+{
+  restart_scan:
+  while (not defined $line or $line eq '')
+  {
+    if (defined($line = <STDIN>))
+    {
+      chomp $line;
+      $curline = $line;
+    } else
+    {
+      $line = ''; $token = '&&&EOF'; return;
+    }
+  }
+  if ($line =~ /^\/\//) { $line = ''; goto restart_scan; }
+  if ($line =~ /^\s+/) { $line = $'; goto restart_scan; }
+  if ($line =~ /^(\d+)/) { $line = $'; $token = $1; return; }
+  if ($line =~ /^([a-zA-Z_]\w*)/) { $line = $'; $token = $1; return; }
+  if ($line =~ /^(\".*?\")/) { $line = $'; $token = $1; return; }
+  if ($line =~ /^(\".*?)\s*$/) # exp. del. inform quotes
+  {
+    $token = $1;
+    $line = <INFILE>;
+    chomp $line;
+    while ($line !~ /^\s*(.*?\")/)
+    {
+      $token .= $line;
+      $line = <INFILE>;
+      chomp $line;
+    }
+    $line =~ /^\s*(.*?\")/;
+    $line = $';
+    $token .= " $1";
+    return;
+  }
+  if ($line =~ /^(.)/) { $line = $'; $token = $1; return; }
+}
+
+sub tokeq
+{
+  return (uc($token) eq uc(shift));
+}
+
+sub tokne
+{
+  return (uc($token) ne uc(shift));
+}
+
+sub expect
+{
+  my $s = shift;
+  my $t = shift || 'unidentified production';
+  if(tokeq($s))
+  {
+    scan();
+  } else
+  {
+    perr "Expected '$s' not '$token' in '$t'";
+    # while (tokne($s)) { scan(); }
+    exit(0) if <STDIN> =~ /^q/;
+  }
+}
+
+### PARSER
+
+# Program ::= {State}.
+sub program
+{
+  scan();
+  print "\$s = join('', <STDIN>); print \"\\n\";\n";
+  print "\$s =~ s/\\n/ /gos;\n";
+
+  while(tokeq('*')) { state(); }
+  expect('&&&EOF');
+  print "print main(\$s);\n";
+}
+
+# State   ::= "*" Name "{" {Rule} ["!" Name] "}".
+sub state
+{
+  expect('*');
+  my $n = defn_name();
+  expect('{');
+  print "sub $n {\n";
+  print "  my \$s = shift;\n";
+  # print "  print \"$n...\\n\";\n";
+  while(tokne('}') and tokne('!')) { rule(); }
+  if(tokeq('!'))
+  {
+    scan();
+    my $q = apply_name();
+    print "  \@_ = (\$s); goto \&$q;\n";
+  }
+  expect('}');
+  print "  return \$s;\n";
+  print "}\n";
+}
+
+# Rule    ::= String "?" String "!" [Name].
+sub rule
+{
+  my $a = lstring();
+  expect('?');
+  my $b = rstring();
+  expect('!');
+  if ($token =~ /^[a-zA-Z]\w+$/)
+  {
+    my $n = apply_name();
+    print "  if(\$s =~ s/$a/$b/e) { \@_ = (\$s); goto \&$n; }\n";
+  } else
+  {
+    print "  if(\$s =~ s/$a/$b/e) { return \$s; }\n";
+  }
+}
+
+sub defn_name
+{
+  my $n = $token;
+  scan();
+  return $n;
+}
+
+sub apply_name
+{
+  my $n = $token;
+  scan();
+  return $n;
+}
+
+# LString ::= {quoted | "few" | "many" | "start" | "finish"}.
+sub lstring
+{
+  my $s = '';
+  while ($token =~ /^\".*?\"$/ or
+         $token eq 'start' or $token eq 'finish' or
+         $token eq 'few' or $token eq 'many')
+  {
+    my $t = $token;
+    if ($t eq 'few')
+    {
+      $s .= "(.*?)";
+    } elsif ($t eq 'many')
+    {
+      $s .= "(.*)";
+    } elsif ($t eq 'start')
+    {
+      $s .= "^";
+    } elsif ($t eq 'finish')
+    {
+      $s .= "\$";
+    } else
+    {
+      $t =~ s/^\"(.*?)\"$/$1/;
+      $s .= quotemeta($t);
+    }
+    scan();
+  }
+  return $s;
+}
+
+# RString ::= {quoted | digit | Name "(" RString ")"}.
+sub rstring
+{
+  my $s = '""';
+  while ($token =~ /^\".*?\"$/ or
+         $token =~ /^\d+$/ or
+         $token =~ /^[a-zA-Z]\w*$/)
+  {
+    my $t = $token;
+    if ($t =~ /^[a-zA-Z]\w*$/)
+    {
+      $s .= " . $t(";
+      scan();
+      expect("(");
+      $s .= rstring();
+      expect(")");
+      $s .= ")";
+    } elsif ($t =~ /^\d+$/)
+    {
+      $s .= " . \$$t";
+      scan();
+    } else
+    {
+      $t =~ s/^\"(.*?)\"$/$1/;
+      $s .= " . \"" . quotemeta($t) . "\"";
+      scan();
+    }
+  }
+  return $s;
+}
+
+### MAIN
+
+program();
+
+### END