From 90ec6ff89d5ae50c465d9960f0d3f1dcdefffebe Mon Sep 17 00:00:00 2001 From: Tyson Dowd Date: Thu, 19 Nov 1998 06:18:23 +0000 Subject: [PATCH] Add rot13 examples to the samples directory. Estimated hours taken: 8 Add rot13 examples to the samples directory. Note: Estimated time is time for contributors, mainly. samples/README: samples/c_interface/README: Fix the README files, they were a little inaccurate in describing some files and directories. --- samples/README | 33 +--------- samples/c_interface/README | 26 ++++++++ samples/rot13/Mmakefile | 29 +++++++++ samples/rot13/README | 25 ++++++++ samples/rot13/rot13_concise.m | 58 +++++++++++++++++ samples/rot13/rot13_gustavo.m | 72 +++++++++++++++++++++ samples/rot13/rot13_juergen.m | 48 ++++++++++++++ samples/rot13/rot13_verbose.m | 116 ++++++++++++++++++++++++++++++++++ 8 files changed, 377 insertions(+), 30 deletions(-) create mode 100644 samples/c_interface/README create mode 100644 samples/rot13/Mmakefile create mode 100644 samples/rot13/README create mode 100644 samples/rot13/rot13_concise.m create mode 100644 samples/rot13/rot13_gustavo.m create mode 100644 samples/rot13/rot13_juergen.m create mode 100644 samples/rot13/rot13_verbose.m diff --git a/samples/README b/samples/README index c17375200..ae3c26fa1 100644 --- a/samples/README +++ b/samples/README @@ -43,36 +43,9 @@ diff This directory contains an implementation of a `diff', which prints the differences between two files. -diff/file.m A module which defines a `file' abstract data type - to hold the lines of text in a file. - -diff/lcsstype.m A module which defines the `lcss' type; used to - represent the longest common subsequence between - two files. - -diff/lcss.m A module which defines a `diff' data type; it - exports a routine for computing the difference - between two `file's, represented as a `diff', - using the "longest common subsequence" algorithm. - -diff/diffs.m Routines for printing `diff's in a couple of - different formats. - -diff/diff.m The top-level driver for the `diff' program; - it contains some "glue" code which handles - the processing of command-line arguments - and calls the routines in file.m and lcss.m. - -diff/Mmake An example of a very short Mmake file. - c_interface This directory contains some examples of mixed - Mercury/C programs using the C interface. + Mercury/C/C++/Fortran programs using the C interface. -c_interface/c_calls_mercury This directory contains a detailed - example of C code calling Mercury code. - -c_interface/mercury_calls_c This directory contains a detailed - example of Mercury code calling C code. - -c_interface/short_example.m A short example of Mercury code calling C. +rot13 This directory contains a few implementations of + rot-13 encoding. diff --git a/samples/c_interface/README b/samples/c_interface/README new file mode 100644 index 000000000..3221c1730 --- /dev/null +++ b/samples/c_interface/README @@ -0,0 +1,26 @@ + +This directory contains some examples of mixed Mercury/C programs using +the C interface. + +short_example.m A short example of Mercury code calling C. + +mercury_calls_c A detailed example of Mercury code + calling C code. + +c_calls_mercury A detailed example of C code calling + Mercury code. + +mercury_calls_cplusplus A detailed example of Mercury code + calling C++ code. + +cplusplus_calls_mercury A detailed example of C++ code calling + Mercury code. + +mercury_calls_fortran This directory contains a detailed + example of Mercury code calling Fortran code. + +simpler_c_calls_mercury A simpler example of C code calling Mercury. + +simpler_cplusplus_calls_mercury A simpler example of C++ code calling + Mercury. + diff --git a/samples/rot13/Mmakefile b/samples/rot13/Mmakefile new file mode 100644 index 000000000..951dec71e --- /dev/null +++ b/samples/rot13/Mmakefile @@ -0,0 +1,29 @@ +#-----------------------------------------------------------------------------# +# This source file is hereby placed in the public domain. -trd (the author). +#-----------------------------------------------------------------------------# + +# samples/rot13/Mmakefile - this is the Makefile for building the sample +# rot13 programs. + +# To build these programs, first install the Mercury compiler, +# type `mmake depend', and then type `mmake'. + +PROGS= rot13_gustavo rot13_juergen rot13_verbose rot13_concise + +DEPENDS=$(PROGS:%=%.depend) + +MAIN_TARGET=all + +MCFLAGS-rot13_concise=--infer-all + +#-----------------------------------------------------------------------------# + +# targets + +.PHONY: all +all : $(PROGS) + +.PHONY: depend +depend: $(DEPENDS) + +#-----------------------------------------------------------------------------# diff --git a/samples/rot13/README b/samples/rot13/README new file mode 100644 index 000000000..322d8aa8e --- /dev/null +++ b/samples/rot13/README @@ -0,0 +1,25 @@ + +This directory contains various implementations of `rot13', which +is a simple encryption technique. + +From the Jargon File: + + rot13 /rot ther'teen/ /n.,v./ [Usenet: from `rotate alphabet + 13 places'] The simple Caesar-cypher encryption that replaces each + English letter with the one 13 places forward or back along the + alphabet, so that "The butler did it!" becomes "Gur ohgyre qvq vg!" + Most Usenet news reading and posting programs include a rot13 + feature. It is used to enclose the text in a sealed wrapper that the + reader must choose to open -- e.g., for posting things that might + offend some readers, or {spoiler}s. A major advantage of rot13 over + rot(N) for other N is that it is self-inverse, so the same code can + be used for encoding and decoding. + +The different implementations are intended to show different styles +of Mercury programs, and different trade-offs that can be made +between conciseness, readability, correctness, error-handling, etc. + +To build these samples, install the Mercury compiler and type + mmake depend + mmake + diff --git a/samples/rot13/rot13_concise.m b/samples/rot13/rot13_concise.m new file mode 100644 index 000000000..02217b788 --- /dev/null +++ b/samples/rot13/rot13_concise.m @@ -0,0 +1,58 @@ +% File: rot13_concise.m +% Main authors: Warwick Harvey +% Fergus Henderson +% +% rot13_concise: +% +% Program to read its input, apply the rot13 algorithm, and write it out +% again. +% +% This version is more concise (but less efficient) than its companion, +% rot13_verbose. +% +% Key features: +% - is independent of character set (e.g. ASCII, EBCDIC) +% - has proper error handling +% + +:- module rot13_concise. + +:- interface. +:- import_module io. + +:- pred main(state, state). +:- mode main(di, uo) is det. + +:- implementation. +:- import_module char, int, string. + +% The length of `alphabet' should be a multiple of `cycle'. +alphabet = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ". +cycle = 26. + +rot_n(N, Char) = RotChar :- + char_to_string(Char, CharString), + ( if sub_string_search(alphabet, CharString, Index) then + NewIndex = (Index + N) mod cycle + cycle * (Index // cycle), + index_det(alphabet, NewIndex, RotChar) + else + RotChar = Char + ). + +rot13(Char) = rot_n(13, Char). + +main --> + read_char(Res), + ( { Res = ok(Char) }, + print(rot13(Char)), + main + ; { Res = eof } + ; { Res = error(ErrorCode) }, + { error_message(ErrorCode, ErrorMessage) }, + stderr_stream(StdErr), + print(StdErr, "rot13: error reading input: "), + print(StdErr, ErrorMessage), + nl(StdErr) + ). + + diff --git a/samples/rot13/rot13_gustavo.m b/samples/rot13/rot13_gustavo.m new file mode 100644 index 000000000..4a3e01690 --- /dev/null +++ b/samples/rot13/rot13_gustavo.m @@ -0,0 +1,72 @@ +% I have another version of rot13. +% +% Gustavo A. Ospina +% +% This version reads a line and prints the line "roted". I think it is as +% declarative as Jurgen's version. Also I handle error and I used predicates +% on your char library. Maybe my version is slower, but it can be discussed. +% +% This source file is hereby placed in the public domain. +% - Gustavo Ospina + +:- module rot13_gustavo. + +:- interface. + +:- import_module io. + +:- pred main(io__state::di,io__state::uo) is det. + +:- implementation. + +:- import_module char,int,list. + +:- pred rot13(char::in,char::out) is det. + +rot13(Char,RotChar) :- + char__is_upper(Char) -> + rot13(Char,0'A,RotChar) + ; + char__is_lower(Char) -> + rot13(Char,0'a,RotChar) + ; + RotChar = Char. + +:- pred rot13(char::in,int::in,char::out) is det. + +rot13(Char,CodeLetterA,RotChar) :- + char__to_int(Char,CodeChar), + RotCode = (CodeChar - CodeLetterA + 13) mod 26 + CodeLetterA, + char__to_int(RChar,RotCode) -> + RotChar = RChar + ; + RotChar = '\a'. + /* Alert character (Error case. To satisfy mode check) */ + +:- pred printRotChars(list(char)::in,io__state::di,io__state::uo) is det. + +printRotChars([]) --> + []. + +printRotChars([Ch|Chs]) --> + {rot13(Ch,RotCh)}, + io__write_char(RotCh), + printRotChars(Chs). + +% Main Program + +main --> + io__read_line(Result), + ( + {Result = ok(Line)}, + printRotChars(Line), + main + ; + {Result = eof, + true} + ; + {Result = error(Error), + io__error_message(Error,Message)}, + io__stderr_stream(Stderr), + io__write_string(Stderr,Message) + ). diff --git a/samples/rot13/rot13_juergen.m b/samples/rot13/rot13_juergen.m new file mode 100644 index 000000000..3f2d77df4 --- /dev/null +++ b/samples/rot13/rot13_juergen.m @@ -0,0 +1,48 @@ +% +% Copyright (C) 1998 Jürgen Stuber +% This file may only be copied under the terms of the GNU General +% Public License - see the file COPYING in the Mercury distribution. +% +% I couldn't resist: +% Jürgen Stuber +% http://www.mpi-sb.mpg.de/~juergen/ + +:- module rot13_juergen. +:- interface. +:- import_module io. + +:- pred main(io__state::di, io__state::uo) is det. + +:- implementation. +:- import_module char, int, require. + +:- pred rot13( char::in, char::out) is det. + +main --> + io__read_char( Result ), + ( { Result = ok( Char ) } -> + { rot13( Char, Rot13Char ) }, + io__write_char( Rot13Char ), + main + + ; { Result = eof } -> + { true } + ; + { error( "read failed" ) } + ). + +rot13( Char, Rot13Char ) :- + char__to_int( Char, Code ), + ( 0'A =< Code, Code =< 0'Z -> + Rot13Code = (Code - 0'A + 13) mod 26 + 0'A + ; 0'a =< Code, Code =< 0'z -> + Rot13Code = (Code - 0'a + 13) mod 26 + 0'a + ; + Rot13Code = Code + ), + ( char__to_int( Ch, Rot13Code ) -> + Rot13Char = Ch + ; + error("too offensive, censored") + ). + diff --git a/samples/rot13/rot13_verbose.m b/samples/rot13/rot13_verbose.m new file mode 100644 index 000000000..2f3ad33e1 --- /dev/null +++ b/samples/rot13/rot13_verbose.m @@ -0,0 +1,116 @@ +% File: rot13_verbose.m +% Main author: Warwick Harvey +% Additional input: Fergus Henderson + +% +% rot13_verbose: +% +% Program to read its input, apply the rot13 algorithm, and write it out +% again. +% +% This version is more verbose (and more efficient) than its companion, +% rot13_concise. +% +% Key features: +% - is independent of character set (e.g. ASCII, EBCDIC) +% - has proper error handling +% - reasonably efficient (uses a table to do the rotation) +% + +:- module rot13_verbose. + +:- interface. +:- import_module io. + +:- pred main(io__state, io__state). +:- mode main(di, uo) is det. + +:- implementation. +:- import_module char, int, require. + + % rot13a/2 + % A table to map the alphabetic characters to their rot13 equivalents + % (fails if the input is not alphabetic). +:- pred rot13a(char, char). +:- mode rot13a(in, out) is semidet. + +rot13a('a', 'n'). +rot13a('b', 'o'). +rot13a('c', 'p'). +rot13a('d', 'q'). +rot13a('e', 'r'). +rot13a('f', 's'). +rot13a('g', 't'). +rot13a('h', 'u'). +rot13a('i', 'v'). +rot13a('j', 'w'). +rot13a('k', 'x'). +rot13a('l', 'y'). +rot13a('m', 'z'). +rot13a('n', 'a'). +rot13a('o', 'b'). +rot13a('p', 'c'). +rot13a('q', 'd'). +rot13a('r', 'e'). +rot13a('s', 'f'). +rot13a('t', 'g'). +rot13a('u', 'h'). +rot13a('v', 'i'). +rot13a('w', 'j'). +rot13a('x', 'k'). +rot13a('y', 'l'). +rot13a('z', 'm'). +rot13a('A', 'N'). +rot13a('B', 'O'). +rot13a('C', 'P'). +rot13a('D', 'Q'). +rot13a('E', 'R'). +rot13a('F', 'S'). +rot13a('G', 'T'). +rot13a('H', 'U'). +rot13a('I', 'V'). +rot13a('J', 'W'). +rot13a('K', 'X'). +rot13a('L', 'Y'). +rot13a('M', 'Z'). +rot13a('N', 'A'). +rot13a('O', 'B'). +rot13a('P', 'C'). +rot13a('Q', 'D'). +rot13a('R', 'E'). +rot13a('S', 'F'). +rot13a('T', 'G'). +rot13a('U', 'H'). +rot13a('V', 'I'). +rot13a('W', 'J'). +rot13a('X', 'K'). +rot13a('Y', 'L'). +rot13a('Z', 'M'). + + % rot13/2 + % Applies the rot13 algorithm to a character. +:- pred rot13(char, char). +:- mode rot13(in, out) is det. + +rot13(Char, RotChar) :- + ( if rot13a(Char, TmpChar) then + RotChar = TmpChar + else + RotChar = Char + ). + +main --> + io__read_char(Res), + ( { Res = ok(Char) }, + { rot13(Char, RotChar) }, + io__write_char(RotChar), + main + ; { Res = eof } + ; { Res = error(ErrorCode) }, + { io__error_message(ErrorCode, ErrorMessage) }, + io__stderr_stream(StdErr), + io__write_string(StdErr, "rot13: error reading input: "), + io__write_string(StdErr, ErrorMessage), + io__nl(StdErr) + ). +