Don't have an account? Register now to chat, post, use our tools, and much more.
» Goto page Previous  1, 2, 3, 4, 5, 6, 7  Next
_player1537 wrote:
Of course I'm serious! Also, I think I may try to steal part of your idea (the interactive terminal) and write that in my C version for practice, if you don't mind, of course.
Go ahead! Are you writing a CLI or GUI version, if you don't mind me asking?
Perhaps CLI, but I think you are doing that. Which one are you doing, and I'll do the other one.
Oh, I'm writing a GUI version... as indicated by the screenshot. (CLI = Python interactive console in a terminal, GUI = something like IDLE on Windows)
Ah, then I'll do CLI Okay, here is the prizm basic merthese interpreter.

Code:
``` ClrText 1->X:1->Y ","->Str 1 While StrCmp(StrMid(Str 1,1,1)," ")/=0         ./=  means not equal to. "Input" ?->Str 1 ClrText For 1->A To StrLen(Str 1) If StrCmp(StrMid(Str 1,A,1),"M")=0 Then If X+5>21:Then 1->X:Y+1->Y:IfEnd If Y>7:Then ClrText:1->X:1->Y:IfEnd Locate X,Y,"Merth" X+5->X IfEnd If StrCmp(StrMid(Str 1,A,1),"E")=0 Then 1->x Y+1->Y If Y>7:Then ClrText:1->Y:IfEnd IfEnd If StrCmp(StrMid(Str 1,A,1),"R")=0 Then X+1->X If X>21:Then Y+1->Y:1->X:IfEnd If Y>8:Then 1->Y:ClrText:1->X:IfEnd IfEnd If StrCmp(StrMid(Str 1,A,1),"T")=0 Then RanInt#(1,13)->D If D+X>21:Then 1->X:Y+1->Y:IfEnd If Y>7:Then ClrText:1->X:1->Y:IfEnd For 1->B To D RanInt#(1,26)->C Locate X,Y,StrMid("ABCDEFGHIJKLMNOPQRSTUVWXYZ",C,1 X+1->X Next IfEnd If StrCmp(StrMid(Str 1,A,1),"H")=0 Then A+1->A If A=StrLen(Str 1)+1 Then Goto Z IfEnd WhileEnd IfEnd Next 1->X:1->Y If StrCmp(StrMid(Str 1,1,1)," ")=0 Then " "->Str 1 Else ","->Str 1 IfEnd 0->K While K/=31                            /=   means not equal to. Getkey->K WhileEnd ClrText WhileEnd Lbl Z ClrText Return ```

I know this is not 100% optimized, I worked on it at 11:00 last night, and was to tired(and lazy) to optimize completely. Also this program is 676 Bytes, and I probably could make that less, well I will do that right now.
A Haskell version. This is literally my first ever Haskell program, so it could probably be greatly improved, but it seems to work.

Code:
```import System.IO import System.Random main :: IO () main = do         end <- hIsEOF stdin         if end         then return ()         else do                 c <- getChar                 s <- merthify c                 putStr s                 main merthify :: Char -> IO [Char] merthify 'm' = return "merth" merthify 'e' = return "\n" merthify 'r' = return " " merthify 't' = do         len <- randomRIO (0,13)         randomString len merthify 'h' = do         skipUntil 'h'         return "" merthify _ = return "" randomString :: Int -> IO String randomString 0 = return "" randomString s = do         c <- randomRIO ('a','z')         xs <- randomString (s - 1)         return (c:xs) skipUntil :: Char -> IO () skipUntil c = do         end <- hIsEOF stdin         if end         then return ()         else do                 r <- getChar                 if r == c                 then return ()                 else skipUntil c```
Made a Merthese Interactive Console in C. Here it is:
Code:
```#include <stdio.h> #include <math.h> #include <string.h> #include <time.h> #include <ncurses.h> #define randbool() (!kerm || rand() % 2) #define BUFFER_SIZE 1024 int main(int argc, char** argv) {     char inputbuffer[BUFFER_SIZE];     int notfinished = true,    kerm = false,    seed = time(NULL),    i = 1,    quiet = false,    reallyquiet = false;             for(;i<argc;i++) {    if( argv[i] == '-' ) {        switch( argv[i] ) {        case 'e':       if( i+1 < argc )           merthterpreter(argv[i+1], kerm);       else           printf("Please specify an expression to evaluate after the -e switch.\n");       i++;       break;        case 'k':       kerm = true;       break;        case 'K':       kerm = false;       break;        case 's':       if( i+1 < argc )           srand(atoi(argv[i+1]));       else           printf("Please specify a number to set the seed to after the -s switch.\n");       i++;       break;        case 'S':       seed = time(NULL);       break;        case 'b':       notfinished = false;       break;        case 'q':       quiet = true;       break;        case 'Q':       reallyquiet = true;       quiet = true;       break;        case 'h':       printf("Usage: ./merthese [-e expression] [-s seed] [-S] [-K] [-k] [-h] [-b] [-q] [-Q]\n\n");       printf("-s number     - Set the seed to `number'\n");       printf("-S            - Set the seed to the current time\n");       printf("-h            - Display this help message\n");       printf("-e expression - Evaluate `expression'\n");       printf("-k            - Set the Merthing @ Kerm flag\n");       printf("-b            - Don't use interactive mode\n");       printf("-q            - Don't display header\n");       printf("-Q            - Don't display any debug info\n");       printf("-K            - Reset the Merthing @ Kerm flag\n\n");       break;        default:       printf("\nUnrecognized switch: %s.  Use -h for help\n", argv[i]+1);        }    } else {        merthterpreter(argv[i], kerm);    }     }     if( !quiet )    printf("\nInteractive Merthese Console - By Tanner Hobson\nUse /help for help\n");         while( notfinished ) {    memset(inputbuffer, '\0', BUFFER_SIZE);    printf("\n>> ");    fgets(inputbuffer, BUFFER_SIZE, stdin);    if( strncmp(inputbuffer, "/quit", 5) == 0 )        notfinished = false;    else if( strncmp(inputbuffer, "/kerm", 5) == 0 )        printf("Merthing @ Kerm flag is now %s.", (kerm = !kerm) ? "on" : "off");    else if( strncmp(inputbuffer, "/seed", 5) == 0 )        if( inputbuffer == '\0' )       printf("Seed is %d",(srand(seed))*0+ seed);        else       printf("Seed is now %d.", srand((seed = atoi(inputbuffer + 6)))*0+ seed);    else if( strncmp(inputbuffer, "/help", 5) == 0 ) {        printf("/kerm - Toggle the Merthing @ Kerm extension\n");        printf("/quit - Exit the interactive terminal\n");        printf("/seed - set the seed to use next\n");        printf("/help - What you are reading now\n\n");        printf("Type in the expression to be evaluated and then press RET");    } else        merthterpreter(inputbuffer, kerm);     }     printf("\n"); } int merthterpreter(char* cur, int kerm) {     int hflag = 0,    j;     char accum = '\0';     for( j = 0; j < strlen( cur ) - 1; j++ ) {    if ( cur[j] == 'h' )        hflag = !hflag;    if ( !hflag ) {        switch ( cur[j] ) {        case 'm':       if( randbool() )           printf("merth");       else           printf("%d", accum);       break;        case 'e':       if( randbool() )           printf("\n");       else           accum++;       break;        case 'r':       if( randbool() )           printf(" ");       else           accum = '\0';       break;        case 't':       {           int times = rand() % ((int)13.4);           for ( ; times >= 0 ; times-- )          printf("%c",(char)((rand() % 26) + 'a'));       }       break;        case 'k':       printf("%c", accum);       break;        }    }     } }```
Source for a Merthese compiler for .NET:

Code:
```using System; using System.CodeDom.Compiler; using System.Collections.Generic; using System.Text; using Microsoft.CSharp; namespace Merthese.Compiler {     public class Program     {         static readonly Dictionary<char, List<string>> functionTable = new Dictionary<char, List<string>>         {             {'m', new List<string>{ "Console.Write(\"merth\");" }},             {'e', new List<string>{ "Console.WriteLine();" }},             {'r', new List<string>{ "Console.Write(\" \");" }},             {'t', new List<string>{ "Console.Write(getRandomString(0.0, 13.4));" }},             {'h', new List<string>{ "/*", "*/" }}         };         static void Main(string[] args)         {             if (args.Length != 1) { Console.WriteLine("Usage: mkc <program>\n"); return; }             StringBuilder code = new StringBuilder();             code.AppendLine("using System;");             code.AppendLine();             code.AppendLine("public class Program {");             code.AppendLine("   static Random random;");             code.AppendLine();             code.AppendLine("   static string getRandomString(double min, double max) {");             code.AppendLine("       int length = (int)(min + random.NextDouble() * (max - min));");             code.AppendLine("       string result = \"\";");             code.AppendLine("       while (length-- > 0)");             code.AppendLine("           result += (char)random.Next(97, 123);");             code.AppendLine("       return result;");             code.AppendLine("   }");             code.AppendLine();             code.AppendLine("   static void Main(string[] args) {");             code.AppendLine("       if (args.Length == 1)");             code.AppendLine("           random = new Random(int.Parse(args));");             code.AppendLine("       else");             code.AppendLine("           random = new Random();");             code.AppendLine();             int h = 0;             foreach (char merthstruction in args)             {                 if (merthstruction == 'h')                     code.AppendLine("\t\t" + functionTable[merthstruction][h++ % 2]);                 else                     code.AppendLine("\t\t" + functionTable[merthstruction]);             }             if ((h % 2) == 1) code.AppendLine("\t\t" + functionTable['h']);             code.AppendLine("   }");             code.AppendLine("}");             new CSharpCodeProvider().CompileAssemblyFromSource(new CompilerParameters(null, "merth.exe", false) { GenerateExecutable = true }, code.ToString());         }     } }```
Oooh, nice. But we need to read from more than just args. What if there's a space. So:

Code:
```using System; using System.CodeDom.Compiler; using System.Collections.Generic; using System.Text; using Microsoft.CSharp; namespace Merthese.Compiler {    public class Program    {       static readonly Dictionary<char, List<string>> functionTable = new Dictionary<char, List<string>>       {          {'m', new List<string>{ "Console.Write(\"merth\");" }},          {'e', new List<string>{ "Console.WriteLine();" }},          {'r', new List<string>{ "Console.Write(\" \");" }},          {'t', new List<string>{ "Console.Write(getRandomString(0.0, 13.4));" }},          {'h', new List<string>{ "/*", "*/" }}       };       static void Main(string[] args)       {          if (args.Length != 1) { Console.WriteLine("Usage: mkc <program>\n"); return; }          StringBuilder code = new StringBuilder();          code.AppendLine("using System;");          code.AppendLine();          code.AppendLine("public class Program {");          code.AppendLine("   static Random random;");          code.AppendLine();          code.AppendLine("   static string getRandomString(double min, double max) {");          code.AppendLine("      int length = (int)(min + random.NextDouble() * (max - min));");          code.AppendLine("      string result = \"\";");          code.AppendLine("      while (length-- > 0)");          code.AppendLine("         result += (char)random.Next(97, 123);");          code.AppendLine("      return result;");          code.AppendLine("   }");          code.AppendLine();          code.AppendLine("   static void Main(string[] args) {");          code.AppendLine("      if (args.Length == 1)");          code.AppendLine("         random = new Random(int.Parse(args));");          code.AppendLine("      else");          code.AppendLine("         random = new Random();");          code.AppendLine();          int h = 0;          foreach (string word in args)          {             foreach (char merthstruction in word)             {                if (merthstruction == 'h')                   code.AppendLine("\t\t" + functionTable[merthstruction][h++ % 2]);                else                   code.AppendLine("\t\t" + functionTable[merthstruction]);             }          }          if ((h % 2) == 1) code.AppendLine("\t\t" + functionTable['h']);          code.AppendLine("   }");          code.AppendLine("}");          new CSharpCodeProvider().CompileAssemblyFromSource(new CompilerParameters(null, "merth.exe", false) { GenerateExecutable = true }, code.ToString());       }    } }```

(untested)
*bump*
I made some modifications from your base compiler:

Code:
```using System; using System.CodeDom.Compiler; using System.Collections.Generic; using System.Text; using Microsoft.CSharp; using System.IO; namespace Merthpiler {    public class Merthpiler {       static readonly Dictionary<char, List<string>> functionTable = new Dictionary<char, List<string>>       {          {'m', new List<string>{ "Console.Write(\"merth\");" }},          {'e', new List<string>{ "Console.WriteLine();" }},          {'r', new List<string>{ "Console.Write(\" \");" }},          {'t', new List<string>{ "Console.Write(getRandomString(0.0, 13.4));" }},          {'h', new List<string>{ "/*", "*/" }}       };       static void Main(string[] args) {          string outFile = "merth.exe";          string codeFile = "";          for (int i = 0; i < args.Length - 1; i++) {             switch (args[i]) {                case "-o":                   outFile = args[++i];                   break;                case "-c":                   codeFile = args[++i];                   break;                default:                   Console.WriteLine("Usage: Merthpiler [-o outputfile] [-c outputcodefile] programfile"); Environment.Exit(-1);                   break;             }          }          string inFile = args[args.Length - 1];          if (!File.Exists(inFile)) { Console.WriteLine(string.Format("Cannot find file: {0}.", inFile)); Environment.Exit(-1); }          StringBuilder code = new StringBuilder();          code.AppendLine("using System;");          code.AppendLine();          code.AppendLine("public class Program {");          code.AppendLine("   static Random random;");          code.AppendLine();          code.AppendLine("   static string getRandomString(double min, double max) {");          code.AppendLine("      int length = (int)(min + random.NextDouble() * (max - min));");          code.AppendLine("      string result = \"\";");          code.AppendLine("      while (length-- > 0)");          code.AppendLine("         result += (char)random.Next(97, 123);");          code.AppendLine("      return result;");          code.AppendLine("   }");          code.AppendLine();          code.AppendLine("   static void Main(string[] args) {");          code.AppendLine("      if (args.Length == 1)");          code.AppendLine("         random = new Random(int.Parse(args));");          code.AppendLine("      else");          code.AppendLine("         random = new Random();");          code.AppendLine();          int h = 0;          using (StreamReader sr = new StreamReader(inFile)) {             while (!sr.EndOfStream) {                char merthstruction = (char)sr.Read();                if (functionTable.ContainsKey(merthstruction)) {                   if (merthstruction == 'h')                      code.AppendLine("\t\t" + functionTable[merthstruction][h++ % 2]);                   else                      code.AppendLine("\t\t" + functionTable[merthstruction]);                }             }          }          if ((h % 2) == 1) code.AppendLine("\t\t" + functionTable['h']);          code.AppendLine("   }");          code.AppendLine("}");          string finalCode = code.ToString();          if (codeFile != "") { using (StreamWriter sr = new StreamWriter(codeFile)) { sr.Write(finalCode); } }          new CSharpCodeProvider().CompileAssemblyFromSource(new CompilerParameters(null, outFile, false) { GenerateExecutable = true }, finalCode);       }    } }```

Now you pass in what you want the output file to be (defaults to "merth.exe"), what file the code will go in if you want it (defaults to ""), and takes in a file rather than the code on the command line. Also, I like your use of the Dictionary.
Nice, just fixed some of those.

Note also that the dictionary has lists instead of strings so that the nondeterministic Kerm/Nikky extensions can be added easily, though I will not be adding them myself.

This should be a little faster than the other implementations, for anyone still looking for seeds...
Ooh, good call. I'll switch that out now .

I just realized I was using the wrong version of the Merthterpreter this whole time, I've been using the one that doesn't take a seed... Time to start over!
Updated (slightly cleaner) RPL version:

Code:
``` \<< "" 1. \-> out hflag   \<<     WHILE DUP "" \=/     REPEAT DUP HEAD       IF DUP "h" ==       THEN 'hflag' -1. STO*       ELSE         IF hflag 0. >         THEN           CASE DUP "m" ==             THEN "merth"             END DUP "e" ==             THEN " "             END DUP "r" ==             THEN " "             END DUP "t" ==             THEN "" 1. RAND 13.4 *               FOR i "abcdefghijklmnopqrstuvwxyz" RAND 26. * DUP SUB +               NEXT             END ""           END 'out' SWAP STO+         END       END DROP TAIL     END DROP out   \>> \>> ```

This one implements the Merthing @ Kerm extension:

Code:
``` \<< "" 1. 0. \-> out hflag accum   \<<     WHILE DUP "" \=/     REPEAT DUP HEAD       IF DUP "h" ==       THEN 'hflag' -1. STO*       ELSE         IF hflag 0. >         THEN           CASE DUP "m" ==             THEN               IF RAND .5 <               THEN "merth"               ELSE accum R\->I \->STR               END             END DUP "e" ==             THEN               IF RAND .5 <               THEN " "               ELSE "" 'accum' 1. STO+               END             END DUP "r" ==             THEN               IF RAND .5 <               THEN " "               ELSE "" 'accum' 0. STO*               END             END DUP "t" ==             THEN "" 1. RAND 13.4 *               FOR i "abcdefghijklmnopqrstuvwxyz" RAND 26. * DUP SUB +               NEXT             END DUP "k" ==             THEN accum CHR             END ""           END 'out' SWAP STO+         END       END DROP TAIL     END DROP out   \>> \>> ```

This is my current attempt at adding the Nikky extension, but looping is buggy (nested looping is broken and the accumulator gets destroyed) and the code is starting to get messy. I'm going to have to either restructure the program or change my approach to make it work properly in a clean way.

Code:
``` @ Program name: MERTH3 \<< "" 1. 0. \-> out hflag accum   \<<     WHILE DUP "" \=/     REPEAT DUP HEAD       IF DUP "h" ==       THEN 'hflag' -1. STO*       ELSE         IF hflag 0. >         THEN           CASE DUP "m" ==             THEN               IF RAND .5 <               THEN "merth"               ELSE accum R\->I \->STR               END             END DUP "e" ==             THEN               IF RAND .5 <               THEN " "               ELSE "" 'accum' 1. STO+               END             END DUP "r" ==             THEN               IF RAND .5 <               THEN " "               ELSE "" 'accum' 0. STO*               END             END DUP "t" ==             THEN "" 1. RAND 13.4 *               FOR i "abcdefghijklmnopqrstuvwxyz" RAND 26. * DUP SUB +               NEXT             END DUP "k" ==             THEN               IF RAND .5 <               THEN accum CHR               ELSE "nikky"               END             END DUP "n" ==             THEN                 @ Get char after the 'n', manually remove it from the command                 @ stream, and then put it back where it was on the stack               SWAP TAIL DUP HEAD NUM 'accum' SWAP STO+ SWAP ""             END DUP "i" ==             THEN                 @ Request string from user and use first char as new                 @ accumulator               "" 'accum' "Character, please!" { 0. } INPUT NUM SWAP STO             END DUP "y" ==             THEN                 @ It wasn't clear to me how looping was supposed to be                 @ implemented, so I made 'y' repeat all the chars up to the                 @ next 'h'.                 @                 @ Get all the looping data and create a substring                 @ containing the chars to loop over             SWAP DUP DUP DUP TAIL HEAD NUM \-> loopcount               \<< "h" + "h" POS \-> loopend                 \<< 3. loopend SUB \-> loopcode                   \<< "" 1. loopcount                       @ Loop by having the program call itself because I                       @ was too lazy to break it up into subroutines.                       @ As a result, there are major issues with looping                       @ that need to be fixed.                     FOR i loopcode MERTH3 +                     NEXT                       @ Chop off now-executed looped code from the command                       @ stream and get the stack back the way it was                     SWAP DUP SIZE loopend SWAP SUB UNROT                   \>>                 \>>               \>>             END ""           END 'out' SWAP STO+         END       END DROP TAIL   @ Chop off just-processed character; ready for next pass     END DROP out   \>> \>> ```
Funny how nikky killed the interpreter.
merthsoft wrote:
Ooh, good call. I'll switch that out now .

I just realized I was using the wrong version of the Merthterpreter this whole time, I've been using the one that doesn't take a seed... Time to start over!
Wow, very impressive work there. >_< This is such a cool and popular project, I might even make it a frontpage news article, if you guys think it's worthy.
That would be awesome! I have said this a few times in IRC, and maybe in this topic, but I think that each we, someone should come up with a quick, easy esoetric language, or even just a small project that doesn't take long to write, and everyone could try to port it to 20 different languages Also, I am going to rewrite my Lisp one to be a little bit more extensible. I also need to edit my console so that it has history, and uses a doubly-linked-list for it.
It would be cool to have a small project every week or so. Maybe not a language, but something short and sweet.
merthsoft wrote:
It would be cool to have a small project every week or so. Maybe not a language, but something short and sweet.
Definitely agreed. For something easy to port across a lot of languages, I guess ideally it wouldn't interface hardware, wouldn't be something that does complicated binary manipulation (since many languages [yes, I'm looking at you, Python] do poorly with binary strings), and would be short but fun.
Taking a different approach, I decided to write a Merthese-to-UserRPL compiler in UserRPL. As far as I know, everything works, including nested loops and accumulator handling in loops. Take that, Nikky! The only thing missing is the ability to choose which extensions are active; the Kerm and Nikky ones are always used.

Interestingly, I found this compiler overall easier to implement than the interpreter, though it probably doesn't look like it from the code. As before, the Merthese code goes on the top of the stack in a string, and executing the program RUN will compile and execute it, leaving the output string on the stack in place of the code string. To just see the resulting code without running it, COMPILE.FULL can be used instead. The generated code requires the pre-made subroutines M, E, R, T, I, and K, which it calls to implement most of the functions (this is done mainly to avoid duplicating many bytes of code over and over again).

On my HP 50g, the execution speed of both the compiler and compiled code seems quite respectable for interpreted UserRPL code.

Code:
``` @ Directory "NIKKY" @ Size: 1923  Circ: # 4ABDh DIR   @@@ Code templates used to dynamically produce RPL code   START.TMPL "\<< 0 \-> \<-accum \<< \\"\\" "   END.TMPL " \>> \>>"   M.TMPL "M + "   E.TMPL "E + "   R.TMPL "R + "   T.TMPL "T + "   K.TMPL "K + "   N.TMPL "@\$1@ '\<-accum' STO+ "   I.TMPL "I "   Y.TMPL "1 @\$1@ FOR i @\$2@ NEXT "   @@@ Subroutines called by compiled code to perform Merthese operations   M   \<<     IF RAND .5 <     THEN "merth"     ELSE \<-accum R\->I \->STR     END   \>>   E   \<<     IF RAND .5 <     THEN " "     ELSE "" '\<-accum' 1. STO+     END   \>>   R   \<<     IF RAND .5 <     THEN " "     ELSE "" '\<-accum' 0. STO*     END   \>>   T   \<< "" 1. RAND 13.4 *     FOR i "abcdefghijklmnopqrstuvwxyz" RAND 26. * DUP SUB +     NEXT   \>>   I   \<< '\<-accum' "Character, please!" { 0. } INPUT NUM SWAP STO   \>>   K   \<<     IF RAND .5 <     THEN \<-accum CHR     ELSE "nikky"     END   \>>   @@@ Take a string of Merthese code and the start position and   @@@ search for the end of the looping structure, assuming that   @@@ given code is already in an outer loop.  Take nested loops into   @@@ account.   LOOPEND   \<< DUP 0 \-> code loopstart pos nestcount     \<<       DO code pos DUP SUB \-> c         \<<           CASE c "y" ==             THEN 'pos' 2 STO+ 'nestcount' 1 STO+             END c "n" ==             THEN 'pos' 2 STO+             END c "h" ==             THEN 'nestcount' 1 STO- 'pos' 1 STO+             END 'pos' 1 STO+           END         \>>       UNTIL nestcount 0 < pos code SIZE > OR       END pos     \>>   \>>   @@@ Compile a subroutine of Merthese code   COMPILE.ROUTINE   \<< DUP SIZE 1. \-> incode insz chrp     \<< ""       WHILE chrp insz \<=       REPEAT incode chrp DUP 1 + SUB DUP HEAD SWAP TAIL \-> c1 c2         \<<           CASE c1 "m" ==             THEN M.TMPL             END c1 "e" ==             THEN E.TMPL             END c1 "r" ==             THEN R.TMPL             END c1 "t" ==             THEN T.TMPL             END c1 "h" ==               @ Skip over to next 'h'             THEN incode chrp 1. + insz SUB "h" POS DUP chrp + SWAP 0.               \=/ SWAP insz IFTE 'chrp' STO ""             END c1 "k" ==             THEN K.TMPL             END c1 "n" ==             THEN               @ Replace string "@\$1@" in 'N' code template with               @ character to write to accumulator             N.TMPL "@\$1@" c2 NUM \->STR SREPL DROP 'chrp' 1 STO+             END c1 "i" ==             THEN I.TMPL             END c1 "y" ==             THEN               @ Replace string "@\$1@" in code template with number of               @ times to loop.             Y.TMPL "@\$1@" c2 NUM \->STR SREPL DROP               @ Replace "@\$2@" with compiled loop body code:             "@\$2@"             incode chrp 2 +    @ Get loop body of Merthese code only             incode OVER LOOPEND DUP 1 -                                @ Find end of loop             'chrp' STO 1 -                                @ Update Merthese character pointer for                                @ next pass through main compiler loop                                @ (will point past the end of this loop                                @ since we're handling it all here)             SUB COMPILE.ROUTINE                                @ Compile the loop code (and any nested                                @ loops, however many levels deep)             SREPL DROP         @ Finally, we can add the compiled loop                                @ body in place of the "@\$2@" placeholder             END ""           END         \>> + 'chrp' 1 STO+       END     \>>   \>>   @@@ Compile Merthese code, generating a full RPL program   COMPILE.FULL   \<< COMPILE.ROUTINE START.TMPL SWAP + END.TMPL +     @ Reformat the code string by converting it to code and then back     @ to a string to make it look nice     STR\-> \->STR   \>>   @@@ Compile Merthese code and immediately execute it   RUN   \<< COMPILE.FULL STR\-> EVAL   \>> END ```

And now for my proposed extension:

Quote:
t: Outputs incrementing sequence of chars starting from accum. char with random length 013.4 (same as for 't' command). Randomly either leaves accum. unmodified or sets it to final char code + 1
e: Randomly outputs one of .,;:-!?'
v: Outputs the accum. char ROT13'ed if it's a letter (ASCII 6590 or 97122), unmodified otherwise
Here's the source code for a 68k Basic implementation that I wrote this morning. It supports the core of the language and the Merthing @ Kerm extension. I think the Nikky extension would be impossible to do with the way I wrote it, and I'm not sure if there's a better way to write it.

It works, but it's a little slow. Maybe a 68k C implementation (which I'll do as well, perhaps) would run better.

It was generated by DaisukeEdit, but after doing that I replaced the "->" character with the string "->", so you won't be able to just plug it back into there. (I did the same with "!=").

Code:
```merthese(cmds) Prgm Local i,j,chr,out,letters,rnd,nexth,accum {"a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z"}->letters Define nexth(cmds)=Func Local i,chr ""->chr 0->i If inString(cmds,"h")=0 Then  Return cmds EndIf While chr!="h"  i+1->i  mid(cmds,i,1)->chr EndWhile Return mid(cmds,i+1) EndFunc " "->chr ""->out 0->accum 0->i ClrIO While chr!=""  i+1->i  mid(cmds,i,1)->chr  If chr="m" Then   If rand()<.5 Then    out&"merth"->out   Else    out&string(accum)->out   EndIf  ElseIf chr="e" Then   If rand()<.5 Then    out&char(13)->out   Else     accum+1->accum   EndIf  ElseIf chr="r" Then   If rand()<.5 Then    out&" "->out   Else    0->accum   EndIf  ElseIf chr="t" Then   rand(13)->rnd   For j,0,rnd    out&letters[rand(26)]->out  EndFor  ElseIf chr="h" Then   nexth(mid(cmds,i+1))->cmds   0->i  ElseIf chr="k" Then   out&char(accum)->out  EndIf EndWhile 0->i " "->chr While chr!=""  i+1->i  mid(out,i,1)->chr  If chr=char(13) Then   Disp mid(out,1,i-1)   mid(out,i+1)->out   0->i  EndIf EndWhile Disp out EndPrgm```

Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

»
» Goto page Previous  1, 2, 3, 4, 5, 6, 7  Next
» All times are GMT - 5 Hours

You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum