previndexinfonext

code guessing, round #63 (completed)

started at ; stage 2 at ; ended at

specification

did you miss me? ahh? I bet you did! this week's challenge is to implement ysl, I hear. submissions may be written in any language.

take a gander at this here document, if you please.

YSL specification

YSL

The lines of the program are stored in a sorted map, where the key is integers and the values are strings which contain a line of code. The interpreter gets a line of code from here every time a statement is run and parses it with a split function. This split function splits by any whitespaces unless it's in a string. Example:

print meow "meow meow"

is parsed as:

["print", "meow", "meow meow"]

Elements in this array are referred to as "parts"

Part replacement

Then, the interpreter evaluates variables and other identifiers. A $ prefix on an identifier means get an integer from a variable. Variables are integer arrays. The string containing the identifier will be replaced with the first value of the variable's array. A ! prefix means string. A string is created from the variable's array, where each element is an ASCII character. A & prefix means the part will be replaced with the next character's ASCII value.

Passing

Then the parsed array is passed to the function named in the first element. The array when passed to the function will have the first element removed.

Self modifying

To write to the program's map, the line number is written before the statement. The line number must also be replaced if it contains an identifier (see Part replacement)

I'm sure we can all agree that this specification is rather terse and ambiguous. worry not, my friend, for in this life you are free! you alone decide how it should be interpreted. the arbiter of YSL's behaviour is you, dear reader! I encourage you to fill in the blanks in this specification on your own.

all that being said, your challenge, given a YSL program, is to compile or evaluate it according to the language's semantics. (which are, as explained previously, decided by you.) as any language is allowed, there is no fixed API.

results

  1. 👑 LyricLy +2 -0 = 2
    1. Olivia
    2. Dolphy
  2. Olivia +0 -1 = -1
    1. LyricLy (was Dolphy)
    2. Dolphy (was LyricLy)
  3. Dolphy +0 -1 = -1

    entries

    you can download all the entries

    entry #1

    written by Olivia
    submitted at
    0 likes

    guesses
    comments 0

    post a comment


    mYSqL.py ASCII text
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    def implement_ysl(program: str, line_number = 2):
        print(line_number)
        # "The lines of the program are stored in a sorted map, where the key is integers
        # and the values are strings which contain a line of code."
        integers = lambda s: all(list(filter(str.isdigit, s)))
        sorted_map = sorted(map(str, program.split('\n')), key=integers)
        # "The interpreter gets a line of code from here every time a statement is run"
        statement = True
        j = -1
        while statement:
            def get():
                nonlocal j
                j += 1
                return sorted_map[j % len(sorted_map)]
            # "and parses it with a split function."
            def split(line: str):
                # "This split function splits by any whitespaces unless it's in a string.
                # Example:
                # ```
                # print meow "meow meow"
                # ```
                # is parsed as:
                # ```
                # ["print", "meow", "meow meow"]
                # ```"
                import regex
                return [s.removeprefix('"').removesuffix('"') for s in 
                        regex.split(r'(?!(?<=".*)(?=.*")) ', line)]
            assert split('print meow "meow meow"') == ['print', 'meow', 'meow meow']
            # "Elements in this array are referred to as "parts""
            parts = split(get())
            # "Then, the interpreter evaluates variables and other identifiers."
            for i in range(len(parts)):
                # A $ prefix on an identifier means get an integer from a variable. 
                variable = None
                if parts[i].startswith('$'):
                    variable = parts[i][1:]
                # "Variables are integer arrays." 
                variables: dict = {'': [line_number]}
                # "The string containing the identifier will be replaced with the
                # first value of the variable's array."
                if array := variables.get(variable):
                    parts[i] = array[0]
                    continue
                # "A ! prefix means string. A string is created from the variable's array,
                # where each element is an ASCII character."
                variable = None
                if parts[i].startswith('!'):
                    variable = parts[i][1:]
                if array := variables.get(variable):
                    parts[i] = ascii(array)
                    continue
                # "A & prefix means the part will be replaced with the next character's
                # ASCII value."
                if parts[i].startswith('&'):
                    import regex
                    next_character = regex.match(r'\X', parts[i][1:]).group()
                    import encodings.idna
                    parts[i] = int.from_bytes(encodings.idna.ToASCII(next_character))
                    continue
            # "Then the parsed array is passed to the function named in the first element."
            function_name = parts[0]
            def pass_to_function(parsed_array: list):
                function = functions[function_name]
                function(parsed_array)
            # The array when passed to the function will have the first element removed."
            def the(array: list):
                array.pop(0)
                nonlocal line_number, j
                if (line_number / array[1] * array[0]).is_integer():
                    line_number *= array[0]
                    line_number //= array[1]
                    print(line_number)
                    j = -1
            functions = {'the': the}
            pass_to_function(parts)
            # "To write to the program's map, the line number is written before the statement."
            line_number_is_written = line_number in parts
            if line_number_is_written:
                statement = line_number
            # "The line number must also be replaced if it contains an identifier (see Part replacement)"
            if str(line_number).isidentifier():
                line_number = '<Part>'
    
    implement_ysl(open('mqpy.YSL', 'rb').read().decode())
    
    mqpy.YSL data
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    the & &[
    the &N &U
    the & &3
    the & &&
    the & &!
    the &M &
    the &_ &
    the &M &
    the & &
    the & &
    the &
     &
    the & &
    the & &
    the &7 &
    

    entry #2

    written by Dolphy
    submitted at
    0 likes

    guesses
    comments 0

    post a comment


    ysl.py ASCII text
    1
    # All functions are no ops
    

    entry #3

    written by LyricLy
    submitted at
    0 likes

    guesses
    comments 0

    post a comment


    my points empty