Talk:2001: An Esolang Odyssey

From Esolang
Jump to navigation Jump to search

Implementation

This is an implementation in Visual Basic. You can provide a program as input, or, if UseSpecifiedCode is set to true, you can run the code inside the string. Compiling code with UseSpecifiedCode is equivalent to (but not quite) compiling 2001: An Esolang Odyssey. I did try to implement command line arguments for this, but it has not been tested thoroughly and appears to not work the best.

Imports System
Imports System.Collections
Imports System.Text.RegularExpressions
Imports System.Numerics

Module _2001_AnEsolangOdyssey
    Dim Code As String()
    Dim Left As New Stack
    Dim Right As New Stack
    ' ---[DIFFERENCES FROM SPECIFICATION]---
    ' The original specification says the cells
    ' should be unbounded, but BigIntegers are
    ' really weird to deal with in Visual Basic.
    '
    ' Therefore, I have used a 64-bit integer instead,
    ' which should fulfill most purposes.
    Dim Current As Long = 0
    Dim MainDepth As Integer = 0
    Dim InputQueue As String = ""

    ' Set this to your computer's newline sequence
    ' for proper command separation.
    Dim YourNewlineSequence As String = "" + Chr(13) + Chr(10)

    ' Set this to True if you want to insert the code
    ' in the interpreter source (in SpecifiedString),
    ' False if you want to get the program from console input.
    '
    ' --[NOTES]--
    ' * Console input programs need to have @End appended to them.
    '   "Stop, Dave." does not suffice since it can appear in the
    '   middle of a program.
    ' * Using True does not make this program a true compiler,
    '   but makes compiling this program equivalent to compiling
    '   2001: An Esolang Odyssey code. You can therefore make
    '   actual 2001: An Esolang Odyssey executables (.exe).
    '   Because of this I have provided a way to use command-line
    '   arguments.
    Dim UseSpecifiedCode As Boolean = False
    ' Set this to True if you want to make
    ' compiled versions of this interpreter
    ' with UseSpecifiedCode set to true.
    '
    ' Commandline args are put to the left of
    ' the starting pointer position, with the
    ' rightmost character of the rightmost
    ' argument being the one directly to
    ' the left of the pointer. 
    '
    ' From left to right, the format is:
    ' * -2 (This provides a marker to allow the code to
    '   stop at the correct point when trying to find the 
    '   first argument. Ascii codes should never be negative
    '   numbers, so this provides a valuable marker.
    ' * Any number of arguments
    '   * A list of ascii codes of the characters of the argument
    '   * -1 (Another marker to get to the beginning or end of an argument)
    '   
    ' A good way to get to the -2 marker is this code snippet:
    ' -----------------------------------------------------------
    ' Hal? Hal! Hal!
    ' What are you doing, Dave?
    ' I'm afraid. I'm afraid, Dave. Dave, my mind is going. I can feel it. I can feel it.
    ' I've picked up a fault in the AE-35 unit.
    ' Hal? Hal! Hal!
    ' Dave, this conversation can serve no purpose anymore. Goodbye.
    ' I'm afraid. I'm afraid, Dave. Dave, my mind is going. I can feel it. I can feel it.
    ' -----------------------------------------------------------
    ' That only works if you are to the right of it, but you can replace
    ' the 4th line in that snippet with
    ' "Well, he acts like he has genuine emotions." to go from the left instead.
    '
    ' The marker/anchor cell idea is from a video by mitxela on YouTube.
    Dim UseCommandLineArgs As Boolean = False

    ' Insert your program here if UseSpecifiedCode is True.
    Dim SpecifiedString As String =
"Good afternoon, gentlemen. I am a Hello World computer. I became operational at Foobar Lane on May 6th, 2020.
I've picked up a fault in the AE-35 unit.
I've picked up a fault in the AE-35 unit.
Close the pod bay doors, HAL.
Stop, Dave."
    Dim SpecifiedCode As String() = SpecifiedString.Split(YourNewlineSequence)


    Sub Main(args As String())
        If Not UseSpecifiedCode Then
            While True
                Dim Line As String = Console.ReadLine
                If Line.Equals("@End") Then
                    Exit While
                End If
                Code.Append(Line)
            End While
        End If
        If UseSpecifiedCode Then
            Code = SpecifiedCode
        End If
        If Not Regex.IsMatch(Code(0), "Good afternoon\, gentlemen\. I am a .* computer\. I became operational at .* on .*\.") Then
            Throw New Exception("I'm sorry Dave, I'm afraid I can't do that. [REASON]: Program did not begin with a proper greeting.")
        End If
        If Not Code(Code.Length - 1).Equals("Stop, Dave.") Then
            Throw New Exception("I'm sorry Dave, I'm afraid I can't do that. [REASON]: Program did not end with ""Stop, Dave.""")
        End If
        Dim I = 0
        While I < Code.Length
            If Code(I).Equals("What are you doing, Dave?") Then
                MainDepth += 1
            ElseIf Code(I).Equals("Dave, this conversation can serve no purpose anymore. Goodbye.") Then
                MainDepth -= 1
            End If
            I += 1
        End While
        If UseCommandLineArgs Then
            Left.Push(CInt(-2))
            For J As Integer = 0 To args.Length
                For K As Integer = 0 To args(J).Length
                    Left.Push(Asc(args(J).Chars(K)))
                Next
                Left.Push(CInt(-1))
            Next
        End If
        MainDepth = 0
        I = 0
        REM :: Comments are above the instructions but indented
        REM :: because indentation is forced in my IDE
        While I < Code.Length
            ' Where N is the number of times " Hal!"
            ' minus the quotes appears at the end of
            ' this instruction, HAL will increment his
            ' current cell by N.
            If Regex.IsMatch(Code(I), "Hal\?( Hal\!)+") Then
                Current = Current + (((Code(I).Length - 4) / 5))
                ' Where N is the number of times "I can feel it"
                ' minus the quotes appears at the end
                ' of this instruction, HAL will decrement
                ' his current cell by N.
            ElseIf Regex.IsMatch(Code(I), "I'm afraid\. I'm afraid\, Dave\. Dave\, my mind is going\.( I can feel it\.)+") Then
                Current = Current - (((Code(I).Length - 53) / 15))
                ' If HAL's current cell is zero, he will
                ' go to the matching loop end. This is a loop start.
            ElseIf Code(I).Equals("What are you doing, Dave?") Then
                If Current = 0 Then
                    Dim Depth = 1
                    While Depth > 0
                        I = I + 1
                        If Code(I).Equals("What are you doing, Dave?") Then
                            Depth = Depth + 1
                        End If
                        If Code(I).Equals("Dave, this conversation can serve no purpose anymore. Goodbye.") Then
                            Depth = Depth - 1
                        End If
                        If I >= Code.Length Then
                            Throw New Exception("I'm sorry Dave, I'm afraid I can't do that. [REASON]: Unmatched loops.")
                        End If
                    End While
                Else
                    MainDepth = MainDepth + 1
                End If
                ' If HAL's current cell is nonzero,
                ' he will go back to the matching
                ' loop start. This is a loop end.
            ElseIf Code(I).Equals("Dave, this conversation can serve no purpose anymore. Goodbye.") Then
                If Not Current = 0 Then
                    Dim Depth = 1
                    While Depth > 0
                        I = I - 1
                        If Code(I).Equals("What are you doing, Dave?") Then
                            Depth = Depth - 1
                        End If
                        If Code(I).Equals("Dave, this conversation can serve no purpose anymore. Goodbye.") Then
                            Depth = Depth + 1
                        End If
                        If I < 0 Then
                            Throw New Exception("I'm sorry Dave, I'm afraid I can't do that. [REASON]: Unmatched loops.")
                        End If
                    End While
                Else
                    MainDepth = MainDepth - 1
                End If
                ' HAL will break out of the innermost
                ' two loops he is in (or one or none if
                ' he isn't in at least two loops).
            ElseIf Code(I).Equals("This mission is too important for me to allow you to jeopardize it.") Then
                If MainDepth = 0 Then
                ElseIf MainDepth = 1 Then
                    Dim Depth = 1
                    While Depth > 0
                        I = I + 1
                        If Code(I).Equals("What are you doing, Dave?") Then
                            Depth = Depth + 1
                        End If
                        If Code(I).Equals("Dave, this conversation can serve no purpose anymore. Goodbye.") Then
                            Depth = Depth - 1
                        End If
                    End While
                Else
                    Dim Depth = 2
                    While Depth > 0
                        I = I + 1
                        If Code(I).Equals("What are you doing, Dave?") Then
                            Depth = Depth + 1
                        End If
                        If Code(I).Equals("Dave, this conversation can serve no purpose anymore. Goodbye.") Then
                            Depth = Depth - 1
                        End If
                    End While
                End If
                ' HAL will break out of all loops he is currently in.
            ElseIf Code(I).Equals("I know I've made some very poor decisions recently, " +
                              "but I can give you my complete assurance that my wor" +
                              "k will be back to normal.") Then
                Dim Depth = MainDepth
                While Depth > 0
                    I = I + 1
                    If Code(I).Equals("What are you doing, Dave?") Then
                        Depth = Depth + 1
                    End If
                    If Code(I).Equals("Dave, this conversation can serve no purpose anymore. Goodbye.") Then
                        Depth = Depth - 1
                    End If
                End While
                ' HAL will move his cell pointer one cell to the left.
            ElseIf Code(I).Equals("I've picked up a fault in the AE-35 unit.") Then
                If Left.Count = 0 Then
                    Left.Push(CInt(0))
                End If
                Right.Push(Current)
                Current = Left.Pop
                ' HAL will move his cell pointer one cell to the right.
            ElseIf Code(I).Equals("Well, he acts like he has genuine emotions.") Then
                If Right.Count = 0 Then
                    Right.Push(CInt(0))
                End If
                Left.Push(Current)
                Current = Right.Pop
                ' HAL will set his current cell to a user
                ' input character; no input and an error
                ' message will be displayed, and he will
                ' set his current cell to zero, but the
                ' program will not be terminated.
                '
                ' ---[DIFFERENCES FROM THE SPECIFICATION]---
                ' This command does not fit the specification.
                ' The original command said to output an error
                ' if no input was given and continue execution
                ' with a cell value of 0.
                '
                ' Unfortunately, I can't figure out a way to check
                ' whether there is still more input.
                '
                ' The implementation here instead inputs more
                ' whenever the input queue is empty, and if
                ' multiple characters are inputted on the line,
                ' it queues them up to be used later.
            ElseIf Code(I).Equals("Open the pod bay doors, HAL.") Then
                InputQueue += Console.ReadLine & Chr(10)
                Dim InputChar = InputQueue.Chars(0)
                InputQueue = InputQueue.Substring(1)
                Current = Asc(InputChar)
                ' HAL will output his current cell as a character.
            ElseIf Code(I).Equals("Close the pod bay doors, HAL.") Then
                Dim OutputChar = Chr(Current)
                Console.Write(OutputChar)
                ' To write a comment, type
                ' "Hal_Memory.EntryAdd: "
                ' (there must be a space at the end).
                ' This isn't actual code and doesn't mean
                ' anything, but it fits the AI context.
                ' You can of course very easily change this
                ' string to something else in this implementation
                ' but that would make it even less portable.
                '
                ' --------------------------------------------
                ' THIS IS NOT IN THE SPECIFICATION, 
                ' AND DEGRADES PORTABILITY.
                ' --------------------------------------------
            ElseIf Code(I).StartsWith("Hal_Memory.EntryAdd: ") Then
                Current = Current + 0
                ' Whitespace only lines or blank lines 
                ' also do nothing, allowing some nice formatting.
                ' --------------------------------------------
                ' THIS IS NOT IN THE SPECIFICATION, 
                ' AND DEGRADES PORTABILITY.
                ' --------------------------------------------
            ElseIf Regex.IsMatch(Code(I), "\s*") Then
                Current = Current + 0
                ' Multiline comments can be done with 
                ' "[[" to start and "]]" to end.
                ' They must be on their own line.
                ' Usually multiline comment borders
                ' should not overlap loop borders,
                ' but there may be use cases for that.
                '
                ' The main thing that will happen when
                ' overlapping a loop and a comment will
                ' be that the loop will start running the comment
                ' if it is valid code and the value is zero,
                ' and it will break out of the loop prematurely
                ' if the value is non-zero and skip the comment entirely.
                ' This can effectively be an if-else construct.
                '
                ' Doing these kinds of things is extremely unstable,
                ' though, and for these reasons it is a bad idea to 
                ' include lines containing only
                ' "What are you doing, Dave?"
                ' or
                ' "Dave, this conversation can serve no purpose anymore. Goodbye."
                ' (without quotes)
                '
                ' If you really need those lines in your comment, 
                ' differentiate them in some way like prepending them
                ' with some symbol.
                '
                ' Break commands should be safe though.
                '
                ' --------------------------------------------
                ' THIS IS NOT IN THE SPECIFICATION, 
                ' AND DEGRADES PORTABILITY.
                ' --------------------------------------------
            ElseIf Code(I).Equals("[[") Then
                While Code(I).Equals("]]")
                    I += 1
                End While
            End If
 



            I = I + 1
        End While
    End Sub
End Module

BoundedBeans (talk) 19:22, 21 August 2022 (UTC)

I've realized recently that the block of code that says If UseCommandLineArgs requires that Then be following it. I'm honestly surprised the program even runs at all. I've changed it in the code block above. BoundedBeans (talk) 01:47, 6 December 2022 (UTC)