/ Esoteric

High level strings in brainfuck

This post is mostly in my compiled language here: https://github.com/P-T-/bftoast/blob/master/asm/asm.lua

The most basic string type is simply null terminated and prefixed:

PUSH potato <<[<] >[>]

This has some limitations though:
1. You cant index dynamically
2. You cant get its length

So ive created a small string library that is much more advanced:

@copy from to temp
    BF $~temp[-]$~to[-]$~from[-$~to+$~temp+$~from]$~temp[-$~from+$~temp]
@copy2 from to1 to2 temp
    BF $~temp[-]$~to1[-]$~to2[-]$~from[-$~to1+$~to2+$~temp+$~from]$~temp[-$~from+$~temp]
@not x temp
    BF $~temp[-]+$~x[$~temp-$~x[-]]$~temp[-$~x+$~temp]
@String.push str
    PUSH ~str <<<<<<[<<<] >>>[>>>]>>>
    BF $~str[-]>[-]>[-]>[-]>[-]>[-]>$=^up
@String.get str i
    BF $~i[$~str>+<$~i-] // str[0].tmp0 = i
    BF $~str>[           // while tmp0
    BF     -             // tmp0--
    BF     [->>>+<<<]    // next tmp0 = tmp0
    BF     >>>           // move to next tmp0
    BF ]                 // we are at the tmp0 of the selected char
    BF <[->+>+<<]        // tmp1,tmp0 = char
    BF >[-<+>]           // char = tmp0
    BF <[                // while char
    BF     >>            // move to tmp1
    BF     [-<<<+>>>]    // prev tmp1 = tmp1
    BF     <<<<<         // move to prev char
    BF ]>>               // we are at str[0].tmp1
    BF [-<<              // while tmp1 tmp--
    BF     $~i+$~str     // i++
    BF >>]<<             // move to str[0].char
@String.length str x
    BF $~str>>>[                   // while char
    BF     >+                      // tmp0++
    BF     [->>>+<<<]              // next tmp0 = tmp0
    BF     >>                      // move to next char
    BF ]>                          // we are at the last tmp0
    BF [->>$=^up$~x+$~str:^up<<]>> // x = tmp0
@String.append str c
    BF $~str:^up                        // seek to after end of string
    BF <<<+>>>[-]>[-]>[-]>              // initialize new char to 1
    BF $~c-[-$~str:^up<<<<<<+>>>>>>$~c] // add x - 1 to char
@String.set str i x
    BF $~i[$~str>+<$~i-]   // str[0].tmp0 = i
    BF $~x[$~str>>+<<$~x-] // str[0].tmp1 = i
    BF $~str>[             // while tmp0
    BF     -               // tmp0--
    BF     [->>>+<<<]      // next tmp0 = tmp0
    BF     >[->>>+<<<]     // next tmp1 = tmp1
    BF     >>              // move to next tmp0
    BF ]                   // we are at the tmp0 of the selected char
    BF <[-]>>[-<<+>>]      // char = tmp1
    BF >[>>>]>>>$=^up      // seek to after end of string
@String.print str
    BF $~str>>>[.>>>]>>>$=~str:^up
@String.println str
    BF $~str>>>[.>>>]>>+13.-3.[-]>`$=~str:^up
@String.readLine str
    X String.push ~str
    BF $~str >>>
    BF ,-13[
    BF     >[-]>[-]>
    BF     ,-13
    BF ]
    BF >,[-]>[-]<<
    BF <<<[+13<<<]
@String.readLine2 str
    X String.push ~str
    BF $~str >>>
    BF ,-10[
    BF     >[-]>[-]>
    BF     ,-10
    BF ]
    BF >[-]>[-]<<
    BF <<<[+10<<<]
@String.equal str1 str2 x s
    BF $~x[-]

    PUSH ~s:temp0 < >
    PUSH ~s:temp1 < >
    PUSH ~s:temp2 < >
    PUSH ~s:temp3 < >

    X String.length ~str1 ~s:temp0
    X String.length ~str2 ~s:temp1
    X copy ~s:temp0 ~s:temp2 ~s:temp3 // s:temp2 = s:temp0

    BF $~s:temp2[-$~s:temp1-$~s:temp2]
    X not ~s:temp1 ~s:temp2

    BF $~s:temp1[ // if lengths are equal
        BF $~x[-]+ // x = 1
        BF $~s:temp0[ // while s:temp0
            // s:temp1,s:temp2 = s:temp0
            X copy2 ~s:temp0 ~s:temp1 ~s:temp2 ~s:temp3

            BF $~s:temp0-
            X String.get ~str1 ~s:temp1
            X String.get ~str2 ~s:temp2
            // s:temp1 = s:temp1 - s:temp2
            BF $~s:temp2[-$~s:temp1-$~s:temp2] 
            BF $~s:temp1[ // if s:temp1
                BF $~x[-] // x = 0
                BF $~s:temp0[-] // temp0 = 0
            BF $~s:temp1[-]]
        BF $~s:temp0]
    BF $~s:temp1[-]]

    POP ~s:temp3 ~s:temp2 ~s:temp1 ~s:temp0
@lazyPrint tmp txt
    BF $~tmp`return ("~txt"):gsub(".",function(c) return "[-]" .. ("+"):rep(c:byte()) .. "." end)`
@lazyString str txt
    X String.push ~str
    BF $~str[-]>[-]>[-]>`return ("~txt"):gsub(".",function(c) return "[-]" .. ("+"):rep(c:byte()) .. ">[-]>[-]>" end)`[-]>[-]>[-]>$=~str:^up

It can be used to create a program like this

@_main
    X lazyString derp Hello
    X String.readLine2 herp

    PUSH potato < >
    PUSH walrus < >
    X String.equal derp herp potato ^S
    BF $walrus[-]+$potato[
        BF $walrus[-]
        X lazyPrint potato equal\n
    BF $potato[-]]$walrus[
        X lazyPrint potato not\32equal\n
    BF $walrus[-]]

It reads a string (terminated with \n) and tells you if it is equal to "Hello" or not.
It compiles to this:

[-]>[-]>[-]>[-]>[-]>[-]<<<<<[<<<][-]>[-]>[-]>[-]++++++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++++++++++++>[-]>[-]>[-]
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++>[-]>[-]>[-]+++++++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++>[-]>[-]>[-]+++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++>[-]>[-]>[-]+++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]<<<<<[<<<] >>>,-----
-----[>[-]>[-]>,----------]>[-]>[-]<<<<<[++++++++++<<<]>>>[>>>]>>>
[-]<<<<<<[<<<]<<<<<<[<<<]>>>[>+[->>>+<<<]>>]>[->>>>>[>>>]>>>>>+<<<
<<<<<[<<<]<<]>>>>>[>+[->>>+<<<]>>]>[->>>>>+<<<<<]>>>>>>>[-]<[-]<<[
->>+>+<<<]>>>[-<<<+>>>]<[-<->][-]+<[>-<[-]]>[-<+>]<[<<<[-]+>>[>>>[
-]<<[-]>[-]<<[->+>+>+<<<]>>>[-<<<+>>>]<<<->[<<<<<<<<<[<<<]<<<<<<[<
<<]>+>>[>>>]>>>>>>[>>>]>>>>>>-]<<<<<<<<<[<<<]<<<<<<[<<<]>[-[->>>+<
<<]>>>]<[->+>+<<]>[-<+>]<[>>[-<<<+>>>]<<<<<]>>[->[>>>]>>>>>>[>>>]>
>>>>>+<<<<<<<<<[<<<]<<<<<<[<<<]>>]>[>>>]>>>>>>[>>>]>>>>>>>[<<<<<<<
<<<[<<<]>+>>[>>>]>>>>>>>-]<<<<<<<<<<[<<<]>[-[->>>+<<<]>>>]<[->+>+<
<]>[-<+>]<[>>[-<<<+>>>]<<<<<]>>[->[>>>]>>>>>>>+<<<<<<<<<<[<<<]>>]>
[>>>]>>>>>>>[-<->]<[<<<[-]>>[-]>[-]]<]>[-]]<<[-]+<[>[-]<[-]+++++++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++.[-]++++++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++.[-]+++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++.[-]++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++.[-]+++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++.[-]++++++++++.[-]]>[<[-]++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++++++.[-]++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++.[-]+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++.[-]+++++
+++++++++++++++++++++++++++.[-]+++++++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.[-]++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++.[-]+++++++++++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++++++.[-]++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++.[-]+++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++++++++++++++++++++++++++++++.[-]+++++++
+++.>[-]]

Note this is suuuuuper slow on an unoptimized interpreter.

High level strings in brainfuck
Share this