previndexinfonext

code guessing, round #39 (completed)

started at ; stage 2 at ; ended at

specification

it seems about time to implement brain-flak. submissions may be written in any language.

brain-flak is a stack-based esolang created by a member of the code golf stack exchange some years ago. inspired by the minimalism of brainfuck, it is an expression-based language written only using brackets.

there are 4 types of brackets: (), [], {} and <>. each program's brackets must be balanced. some implementations support line comments with # or block comments with #{...}, but this is not a requirement for this challenge.

the language's only data type is the integer, which can be both negative and positive. these integers traditionally have arbitrary size, but you may implement them as signed 64-bit integers if you like.

there are 2 stacks, the 'left' and 'right' stack. when the program starts, the left stack is the 'current' stack. any input to the program starts out on the left stack, with the rightmost values at the top. popping an empty stack is valid and yields 0.

each program in the language executes some side effects and evaluates to an integer. the concatenation XY of two programs X and Y will perform the effects of X, then Y, and evaluate to the sum of their results.

first I will describe the behaviour of brackets with nothing inside them, known as nilads:

recall that concatenating programs sums them, so ()()() evaluates to 3 and {}() pops the stack and adds one to the value before returning it.

the other 4 operations, monads, take other programs as arguments:

note that (...) evaluates to the value pushed, so it can be chained such as in ((())) to push 1 twice. {...} evaluates to the sum of all its runs, such that e.g. ({{}}) pushes the sum of the values popped.

your implementation should accept a program and input in the form of a sequence of integers, execute the program and output the contents of the current stack at the end. you do not have to reject invalid programs.

results

  1. 👑 taswelll +7 -2 = 5
    1. razetime (was Anima Libera)
    2. LyricLy
    3. soup girl (was kimapr)
    4. GNU Radio Shows
    5. ultlang
    6. olus2000
    7. Anima Libera (was razetime)
    8. Olivia
    9. luatic
    10. kimapr (was soup girl)
    11. Palaiologos
  2. Olivia +4 -2 = 2
    1. taswelll (was Anima Libera)
    2. LyricLy
    3. Anima Libera (was kimapr)
    4. GNU Radio Shows
    5. soup girl (was ultlang)
    6. razetime (was olus2000)
    7. kimapr (was razetime)
    8. luatic
    9. ultlang (was soup girl)
    10. olus2000 (was taswelll)
    11. Palaiologos
  3. razetime +2 -0 = 2
    1. soup girl (was Anima Libera)
    2. LyricLy
    3. olus2000 (was kimapr)
    4. luatic (was GNU Radio Shows)
    5. ultlang
    6. taswelll (was olus2000)
    7. Anima Libera (was Olivia)
    8. Palaiologos (was luatic)
    9. kimapr (was soup girl)
    10. GNU Radio Shows (was taswelll)
    11. Olivia (was Palaiologos)
  4. olus2000 +2 -1 = 1
    1. Palaiologos (was Anima Libera)
    2. Olivia (was LyricLy)
    3. LyricLy (was kimapr)
    4. GNU Radio Shows
    5. Anima Libera (was ultlang)
    6. ultlang (was razetime)
    7. razetime (was Olivia)
    8. taswelll (was luatic)
    9. soup girl
    10. kimapr (was taswelll)
    11. luatic (was Palaiologos)
  5. kimapr +1 -0 = 1
    1. Anima Libera
    2. GNU Radio Shows (was LyricLy)
    3. Olivia (was GNU Radio Shows)
    4. LyricLy (was ultlang)
    5. soup girl (was olus2000)
    6. olus2000 (was razetime)
    7. razetime (was luatic)
    8. taswelll (was soup girl)
    9. luatic (was taswelll)
    10. ultlang (was Palaiologos)
  6. GNU Radio Shows +4 -4 = 0
    1. Anima Libera
    2. LyricLy
    3. soup girl (was kimapr)
    4. kimapr (was ultlang)
    5. razetime (was olus2000)
    6. taswelll (was razetime)
    7. Olivia
    8. ultlang (was luatic)
    9. luatic (was soup girl)
    10. olus2000 (was taswelll)
    11. Palaiologos
  7. Anima Libera +1 -2 = -1
    1. GNU Radio Shows (was LyricLy)
    2. Olivia (was kimapr)
    3. kimapr (was GNU Radio Shows)
    4. razetime (was ultlang)
    5. Palaiologos (was olus2000)
    6. olus2000 (was razetime)
    7. taswelll (was Olivia)
    8. ultlang (was luatic)
    9. soup girl
    10. luatic (was taswelll)
    11. LyricLy (was Palaiologos)
  8. ultlang +1 -2 = -1
    1. kimapr (was Anima Libera)
    2. GNU Radio Shows (was LyricLy)
    3. razetime (was kimapr)
    4. Anima Libera (was GNU Radio Shows)
    5. Palaiologos (was olus2000)
    6. olus2000 (was razetime)
    7. luatic (was Olivia)
    8. soup girl (was luatic)
    9. Olivia (was soup girl)
    10. taswelll
    11. LyricLy (was Palaiologos)
  9. luatic +1 -2 = -1
    1. razetime (was Anima Libera)
    2. GNU Radio Shows (was LyricLy)
    3. Anima Libera (was kimapr)
    4. Palaiologos (was GNU Radio Shows)
    5. soup girl (was ultlang)
    6. Olivia (was olus2000)
    7. olus2000 (was razetime)
    8. LyricLy (was Olivia)
    9. kimapr (was soup girl)
    10. taswelll
    11. ultlang (was Palaiologos)
  10. Palaiologos +2 -4 = -2
    1. razetime (was Anima Libera)
    2. LyricLy
    3. luatic (was kimapr)
    4. GNU Radio Shows
    5. Olivia (was ultlang)
    6. soup girl (was olus2000)
    7. kimapr (was razetime)
    8. olus2000 (was Olivia)
    9. taswelll (was luatic)
    10. ultlang (was soup girl)
    11. Anima Libera (was taswelll)
  11. soup girl +0 -2 = -2
    1. LyricLy +1 -5 = -4
      1. ultlang (was Anima Libera)
      2. Anima Libera (was kimapr)
      3. soup girl (was GNU Radio Shows)
      4. taswelll (was ultlang)
      5. kimapr (was razetime)
      6. GNU Radio Shows (was Olivia)
      7. razetime (was luatic)
      8. luatic (was soup girl)
      9. Olivia (was taswelll)
      10. Palaiologos

    entries

    you can download all the entries

    entry #1

    written by Anima Libera
    submitted at
    0 likes

    guesses
    comments 1
    jan Wiki

    the term "sus" indicating suspicion or uncertainty gained popularity thanks to a certain game even though it was in use prior to the games launch further terminology and internet memes that surged in popularity and were influenced by among us are "sussy" and "sussy baka" terms evolved from "sus" the ironic meme "when the imposter is sus" generally paired with a manipulated image of jerma985 and the humorous intentional misspelling of "among us" as "amogus" are other terms associated with the game moreover the "among us everywhere" meme which involves spotting objects reminiscent of the games crewmate character in unexpected places also gained traction in september 2022 "sus" was included in the merriam-webster dictionary


    post a comment


    389.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
    import sys
    *t,r,a,n,s=[],sys.argv,[[]],lambda p:sum(map(u,p))
    for u in a[2:]:t+=int(u),
    for w in a[1]:
     if w in"([{<":n+=[],
     if w in")]}>":*n,e=n;n[-1]+=(w,e),
    def u(v):
     c,x=v;z=0
     global t,r
     if")"==c:
      z=1
      if x:z=s(x);t+=z,
     elif"]"==c:z=-s(x)if x else len(t)
     elif"}"==c:
      if x:
       while(not t)or t[-1]:z+=s(x)
      elif t:*t,z=t
     elif x:s(x)
     else:t,r=r,t
     return z
    s(n[0])
    print(t)
    

    entry #2

    written by LyricLy
    submitted at
    3 likes

    guesses
    comments 3
    LyricLy

    dead link


    LyricLy *known at the time as [author of #2]

    oops its supposed to be https://streamablecom/k2y8fq


    LyricLy

    👍


    post a comment


    39.nro data
    Makefile magic text fragment for file(1) cmd, 1st line "#---------------------------------------------------------------------------------", 2nd line ".SUFFIXES:"
      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
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    #---------------------------------------------------------------------------------
    .SUFFIXES:
    #---------------------------------------------------------------------------------
    
    ifeq ($(strip $(DEVKITPRO)),)
    $(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>/devkitpro")
    endif
    
    TOPDIR ?= $(CURDIR)
    include $(DEVKITPRO)/libnx/switch_rules
    
    #---------------------------------------------------------------------------------
    # TARGET is the name of the output
    # BUILD is the directory where object files & intermediate files will be placed
    # SOURCES is a list of directories containing source code
    # DATA is a list of directories containing data files
    # INCLUDES is a list of directories containing header files
    # ROMFS is the directory containing data to be added to RomFS, relative to the Makefile (Optional)
    #
    # NO_ICON: if set to anything, do not use icon.
    # NO_NACP: if set to anything, no .nacp file is generated.
    # APP_TITLE is the name of the app stored in the .nacp file (Optional)
    # APP_AUTHOR is the author of the app stored in the .nacp file (Optional)
    # APP_VERSION is the version of the app stored in the .nacp file (Optional)
    # APP_TITLEID is the titleID of the app stored in the .nacp file (Optional)
    # ICON is the filename of the icon (.jpg), relative to the project folder.
    #   If not set, it attempts to use one of the following (in this order):
    #     - <Project name>.jpg
    #     - icon.jpg
    #     - <libnx folder>/default_icon.jpg
    #
    # CONFIG_JSON is the filename of the NPDM config file (.json), relative to the project folder.
    #   If not set, it attempts to use one of the following (in this order):
    #     - <Project name>.json
    #     - config.json
    #   If a JSON file is provided or autodetected, an ExeFS PFS0 (.nsp) is built instead
    #   of a homebrew executable (.nro). This is intended to be used for sysmodules.
    #   NACP building is skipped as well.
    #---------------------------------------------------------------------------------
    TARGET		:=	$(notdir $(CURDIR))
    BUILD		:=	build
    SOURCES		:=	.
    DATA		:=	data
    INCLUDES	:=	include
    APP_TITLE   :=  cg \#39
    APP_AUTHOR  :=  You!
    ICON        :=  icon.jpg
    
    #---------------------------------------------------------------------------------
    # options for code generation
    #---------------------------------------------------------------------------------
    ARCH	:=	-march=armv8-a+crc+crypto -mtune=cortex-a57 -mtp=soft -fPIE
    
    CFLAGS	:=	-g -Wall -O2 -ffunction-sections \
    			$(ARCH) $(DEFINES)
    
    CFLAGS	+=	$(INCLUDE) -D__SWITCH__
    
    CXXFLAGS	:= $(CFLAGS) -fno-rtti -fno-exceptions
    
    ASFLAGS	:=	-g $(ARCH)
    LDFLAGS	=	-specs=$(DEVKITPRO)/libnx/switch.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
    
    LIBS	:= -lnx
    
    #---------------------------------------------------------------------------------
    # list of directories containing libraries, this must be the top level containing
    # include and lib
    #---------------------------------------------------------------------------------
    LIBDIRS	:= $(PORTLIBS) $(LIBNX)
    
    
    #---------------------------------------------------------------------------------
    # no real need to edit anything past this point unless you need to add additional
    # rules for different file extensions
    #---------------------------------------------------------------------------------
    ifneq ($(BUILD),$(notdir $(CURDIR)))
    #---------------------------------------------------------------------------------
    
    export OUTPUT	:=	$(CURDIR)/$(TARGET)
    export TOPDIR	:=	$(CURDIR)
    
    export VPATH	:=	$(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
    			$(foreach dir,$(DATA),$(CURDIR)/$(dir))
    
    export DEPSDIR	:=	$(CURDIR)/$(BUILD)
    
    CFILES		:=	$(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
    CPPFILES	:=	$(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
    SFILES		:=	$(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
    BINFILES	:=	$(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
    
    #---------------------------------------------------------------------------------
    # use CXX for linking C++ projects, CC for standard C
    #---------------------------------------------------------------------------------
    ifeq ($(strip $(CPPFILES)),)
    #---------------------------------------------------------------------------------
    	export LD	:=	$(CC)
    #---------------------------------------------------------------------------------
    else
    #---------------------------------------------------------------------------------
    	export LD	:=	$(CXX)
    #---------------------------------------------------------------------------------
    endif
    #---------------------------------------------------------------------------------
    
    export OFILES_BIN	:=	$(addsuffix .o,$(BINFILES))
    export OFILES_SRC	:=	$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
    export OFILES 	:=	$(OFILES_BIN) $(OFILES_SRC)
    export HFILES_BIN	:=	$(addsuffix .h,$(subst .,_,$(BINFILES)))
    
    export INCLUDE	:=	$(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
    			$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
    			-I$(CURDIR)/$(BUILD)
    
    export LIBPATHS	:=	$(foreach dir,$(LIBDIRS),-L$(dir)/lib)
    
    ifeq ($(strip $(CONFIG_JSON)),)
    	jsons := $(wildcard *.json)
    	ifneq (,$(findstring $(TARGET).json,$(jsons)))
    		export APP_JSON := $(TOPDIR)/$(TARGET).json
    	else
    		ifneq (,$(findstring config.json,$(jsons)))
    			export APP_JSON := $(TOPDIR)/config.json
    		endif
    	endif
    else
    	export APP_JSON := $(TOPDIR)/$(CONFIG_JSON)
    endif
    
    ifeq ($(strip $(ICON)),)
    	icons := $(wildcard *.jpg)
    	ifneq (,$(findstring $(TARGET).jpg,$(icons)))
    		export APP_ICON := $(TOPDIR)/$(TARGET).jpg
    	else
    		ifneq (,$(findstring icon.jpg,$(icons)))
    			export APP_ICON := $(TOPDIR)/icon.jpg
    		endif
    	endif
    else
    	export APP_ICON := $(TOPDIR)/$(ICON)
    endif
    
    ifeq ($(strip $(NO_ICON)),)
    	export NROFLAGS += --icon=$(APP_ICON)
    endif
    
    ifeq ($(strip $(NO_NACP)),)
    	export NROFLAGS += --nacp=$(CURDIR)/$(TARGET).nacp
    endif
    
    ifneq ($(APP_TITLEID),)
    	export NACPFLAGS += --titleid=$(APP_TITLEID)
    endif
    
    ifneq ($(ROMFS),)
    	export NROFLAGS += --romfsdir=$(CURDIR)/$(ROMFS)
    endif
    
    .PHONY: $(BUILD) clean all
    
    #---------------------------------------------------------------------------------
    all: $(BUILD)
    
    $(BUILD):
    	@[ -d $@ ] || mkdir -p $@
    	@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
    
    #---------------------------------------------------------------------------------
    clean:
    	@echo clean ...
    ifeq ($(strip $(APP_JSON)),)
    	@rm -fr $(BUILD) $(TARGET).nro $(TARGET).nacp $(TARGET).elf
    else
    	@rm -fr $(BUILD) $(TARGET).nsp $(TARGET).nso $(TARGET).npdm $(TARGET).elf
    endif
    
    
    #---------------------------------------------------------------------------------
    else
    .PHONY:	all
    
    DEPENDS	:=	$(OFILES:.o=.d)
    
    #---------------------------------------------------------------------------------
    # main targets
    #---------------------------------------------------------------------------------
    ifeq ($(strip $(APP_JSON)),)
    
    all	:	$(OUTPUT).nro
    
    ifeq ($(strip $(NO_NACP)),)
    $(OUTPUT).nro	:	$(OUTPUT).elf $(OUTPUT).nacp
    else
    $(OUTPUT).nro	:	$(OUTPUT).elf
    endif
    
    else
    
    all	:	$(OUTPUT).nsp
    
    $(OUTPUT).nsp	:	$(OUTPUT).nso $(OUTPUT).npdm
    
    $(OUTPUT).nso	:	$(OUTPUT).elf
    
    endif
    
    $(OUTPUT).elf	:	$(OFILES)
    
    $(OFILES_SRC)	: $(HFILES_BIN)
    
    #---------------------------------------------------------------------------------
    # you need a rule like this for each extension you use as binary data
    #---------------------------------------------------------------------------------
    %.bin.o	%_bin.h :	%.bin
    #---------------------------------------------------------------------------------
    	@echo $(notdir $<)
    	@$(bin2o)
    
    -include $(DEPENDS)
    
    #---------------------------------------------------------------------------------------
    endif
    #---------------------------------------------------------------------------------------
    
    README.txt ASCII text
    1
    2
    install devkitpro packages switch-dev and devkita64, then run make. or use the included .nro
    if you have no switch see demonstration.mp4
    
    demonstration.mp4 external link to streamable.com
    icon.jpg JPEG image data, JFIF standard 1.01, resolution (DPI), density 72x72, segment length 16, Exif Standard: [TIFF image data, little-endian, direntries=7, orientation=upper-left, xresolution=98, yresolution=106, resolutionunit=2, software=GIMP 2.10.34, datetime=2023:07:20 20:35:48], progressive, precision 8, 256x256, components 3
    interpreter.h 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
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    typedef struct {
        enum {
            One,
            Height,
            Pop,
            Toggle,
            Open,
            Push,
            Negate,
            Drop,
            LoopOpen,
            LoopEnd,
        } type;
        size_t target;
    } Token;
    
    #define token(x) ((Token) {.type = (x)})
    
    typedef struct {
        Token tokens[PROGRAM_SIZE];
        size_t tokens_size;
    } Tokens;
    
    Tokens lex(char *program) {
        Tokens p;
        p.tokens_size = 0;
        #define push_token(x) do { p.tokens[p.tokens_size++] = (x); } while (0)
    
        size_t open_brackets[PROGRAM_SIZE];
        size_t open_brackets_size = 0;
    
        for (size_t i = 0; program[i]; i++) {
            switch (program[i]) {
                case '(': case '[': case '<':
                    push_token(token(Open));
                    break;
                #define match_last(x, a, b) if (p.tokens_size && p.tokens[p.tokens_size-1].type == Open) p.tokens[p.tokens_size-1] = token(a); else push_token(token(b));
                case ')': match_last('(', One, Push); break;
                case ']': match_last('[', Height, Negate); break;
                case '>': match_last('<', Toggle, Drop); break;
                case '{':
                    open_brackets[open_brackets_size++] = p.tokens_size;
                    push_token(token(LoopOpen));
                    break;
                case '}':
                    open_brackets_size--;
                    if (p.tokens_size && p.tokens[p.tokens_size-1].type == LoopOpen) {
                        p.tokens[p.tokens_size-1] = token(Pop);
                    } else {
                        size_t idx = open_brackets[open_brackets_size];
                        p.tokens[idx].target = p.tokens_size;
                        push_token(((Token) {.type = LoopEnd, .target = idx}));
                    }
                    break;
            }
        }
    
        return p;
    }
    
    Stack execute(Stack active, char *program) {
        Tokens p = lex(program);
        Stack inactive = {0};
        Stack third = {0};
        stack_push(&third, 0);
    
        for (size_t i = 0; i < p.tokens_size; i++) {
            Token t = p.tokens[i];
            switch (t.type) {
                case One:
                    (*stack_peek(&third))++;
                    break;
                case Height:
                    *stack_peek(&third) += active.size;
                    break;
                case Pop:
                    *stack_peek(&third) += active.size ? stack_pop(&active) : 0;
                    break;
                case Toggle:
                    Stack tmp = active;
                    active = inactive;
                    inactive = tmp;
                    break;
                case Open:
                    stack_push(&third, 0);
                    break;
                case Push: {
                    int64_t x = stack_pop(&third);
                    *stack_peek(&third) += x;
                    stack_push(&active, x);
                    break;
                }
                case Negate: {
                    int64_t x = stack_pop(&third);
                    *stack_peek(&third) -= x;
                    break;
                }
                case Drop:
                    stack_pop(&third);
                    break;
                case LoopOpen:
                    if (!active.size || !*stack_peek(&active)) i = t.target;
                    break;
                case LoopEnd:
                    if (active.size && *stack_peek(&active)) i = t.target;
                    break;
            }
        }
    
        stack_destroy(&inactive);
        stack_destroy(&third);
        return active;
    }
    
    main.c 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
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    #define PROGRAM_SIZE 500
    #define INPUT_SIZE 10
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <stdbool.h>
    #include <inttypes.h>
    #include <switch.h>
    #include "stack.h"
    #include "interpreter.h"
    
    #define error(s, kind) do { strncpy(string, (s), string_size); return SwkbdTextCheckResult_##kind; } while (0)
    
    SwkbdTextCheckResult is_balanced(char* string, size_t string_size) {
        char stack[500];
        size_t height = 0;
        bool non_bracket = false;
    
        for (size_t i = 0; string[i]; i++) {
            char c = string[i];
            switch (string[i]) {
                case '<': case '{': case '[': case '(':
                    stack[height++] = c;
                    break;
    
                #define ensure(x) if (!height) error("Unexpected close bracket.", Bad); else if (stack[--height] != (x)) error("Brackets are mismatched.", Bad); else {}
                case '>': ensure('<'); break;
                case ']': ensure('['); break;
                case ')': ensure('('); break;
                case '}': ensure('{'); break;
    
                case ' ': case '\n': break;
                default: non_bracket = true;
            } 
        }
    
        if (height) error("Unclosed bracket.", Bad);
        if (non_bracket) error("Some characters are not brackets and will be ignored.", Prompt);
    
        return SwkbdTextCheckResult_OK;
    }
    
    void query_program(char *program) {
        SwkbdConfig kbd;
        Result rc = swkbdCreate(&kbd, 0);
        if (!R_SUCCEEDED(rc)) return;
        swkbdConfigMakePresetDefault(&kbd);
    
        swkbdConfigSetInitialText(&kbd, program);
        swkbdConfigSetGuideText(&kbd, "Program (sorry, it only lets me do 500 characters...)");
        swkbdConfigSetTextCheckCallback(&kbd, is_balanced);
    
        char out[PROGRAM_SIZE+1] = {0};
        rc = swkbdShow(&kbd, out, sizeof out);
    
        if (R_SUCCEEDED(rc)) {
            strcpy(program, out);
        }
    
        swkbdClose(&kbd);
    }
    
    void query_input(int64_t *n) {
        SwkbdConfig kbd;
        Result rc = swkbdCreate(&kbd, 0);
        if (!R_SUCCEEDED(rc)) return;
        swkbdConfigMakePresetDefault(&kbd);
    
        char initial[INPUT_SIZE+1];
        snprintf(initial, sizeof initial, "%" PRId64, *n);
        swkbdConfigSetInitialText(&kbd, initial);
    
        swkbdConfigSetType(&kbd, SwkbdType_NumPad);
        swkbdConfigSetHeaderText(&kbd, "Enter an input value.");
        swkbdConfigSetStringLenMax(&kbd, INPUT_SIZE);
        swkbdConfigSetTextDrawType(&kbd, SwkbdTextDrawType_Line);
    
        char out[INPUT_SIZE+1];
        rc = swkbdShow(&kbd, out, sizeof out);
    
        if (R_SUCCEEDED(rc) && *out) {
            *n = atoll(out);
        }
    
        swkbdClose(&kbd);
    }
    
    typedef enum {
        Input,
        Program,
        Execute,
    } Selected;
    
    typedef struct {
        Stack input;
        Stack output;
        size_t selected_input;
        Selected selected;
        char program[PROGRAM_SIZE+1];
    } InputState;
    
    void clear(void) {
        printf("\033[2J");
    }
    
    void cyan(void) {
        printf("\033[36;1m");
    }
    
    void green(void) {
        printf("\033[32;1m");
    }
    
    void reset(void) {
        printf("\033[0m");
    }
    
    void print_state(InputState *state) {
        clear();
        printf("Move to select\nA to edit value\nY to push input\nX to pop input\n+ to exit\n\nInputs: ");
    
        for (size_t i = 0; i < state->input.size; i++) {
            if (state->selected == Input && i == state->selected_input) cyan();
            printf("%" PRId64 " ", state->input.values[i]);
            reset();
        }
    
        if (state->selected == Program) cyan();
        printf("\nProgram:\n%s\n\n", state->program);
        reset();
    
        if (state->selected == Execute) cyan();
        printf("Execute\n");
        reset();
    
        green();
        for (size_t i = 0; i < state->output.size; i++) {
            printf("%" PRId64 " ", state->output.values[i]);
        }
        reset();
    
        consoleUpdate(NULL);
    }
    
    void correct_selected(InputState *state) {
        consoleUpdate(NULL);
        Selected min = state->input.size ? Input : Program;
        Selected max = Execute;
        if (state->selected < min) state->selected = min;
        if (state->selected > max) state->selected = max;
    }
    
    int main(void) {
        consoleInit(NULL);
        padConfigureInput(1, HidNpadStyleSet_NpadStandard);
        PadState pad;
        padInitializeDefault(&pad);
    
        InputState state = {.selected = Program};
        print_state(&state);
    
        while (appletMainLoop()) {
            padUpdate(&pad);
    
            u64 down = padGetButtonsDown(&pad);
    
            if (down & HidNpadButton_Plus) break;
            if (down & HidNpadButton_A) {
                switch (state.selected) {
                    case Input:
                        query_input(&state.input.values[state.selected_input]);
                        break;
                    case Program:
                        query_program(state.program);
                        break;
                    case Execute:
                        stack_destroy(&state.output);
                        state.output = execute(stack_clone(&state.input), state.program);
                        break;
                }
            }
            if (down & HidNpadButton_Y) stack_push(&state.input, 0);
            if (down & HidNpadButton_X && state.input.size) stack_pop(&state.input);
            if (down & HidNpadButton_AnyUp) {
                state.selected--;
                correct_selected(&state);
            }
            if (down & HidNpadButton_AnyDown) {
                state.selected++;
                correct_selected(&state);
            }
            if (state.selected == Input) {
                if (down & HidNpadButton_AnyLeft && state.selected_input) state.selected_input--;
                if (down & HidNpadButton_AnyRight) state.selected_input++;
                if (state.selected_input >= state.input.size) state.selected_input = state.input.size-1;
            }
            if (down) print_state(&state);
        }
    
        stack_destroy(&state.input);
        stack_destroy(&state.output);
        consoleExit(NULL);
    }
    
    stack.h 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
    #include <stdint.h>
    #include <malloc.h>
    #include <string.h>
    
    typedef struct {
        int64_t *values;
        size_t size;
        size_t capacity;
    } Stack;
    
    int64_t *stack_push(Stack *s, int64_t val) {
        if (s->size == s->capacity) {
            s->capacity = s->capacity ? s->capacity * 2 : 64;
            s->values = realloc(s->values, s->capacity * sizeof (int64_t));
        }
        int64_t *p = &s->values[s->size++];
        *p = val;
        return p;
    }
    
    int64_t *stack_peek(Stack *s) {
        return &s->values[s->size-1];
    }
    
    int64_t stack_pop(Stack *s) {
        return s->values[--s->size];
    }
    
    Stack stack_clone(Stack *s) {
        Stack c = *s;
        c.values = malloc(c.capacity * sizeof (int64_t));
        memcpy(c.values, s->values, c.size * sizeof (int64_t));
        return c;
    }
    
    void stack_destroy(Stack *s) {
        free(s->values);
    }
    

    entry #3

    written by kimapr
    submitted at
    2 likes

    guesses
    comments 0

    post a comment


    main.rs 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
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    /*
     * BrainFlak (https://esolangs.org/wiki/Brain-Flak) interpreter in Rust.
     * Values are signed 64-bit integers or larger.
     * No syntax errors. Any valid opening bracket can be closed with any valid
     * closing bracket, but any combination not specified below causes undefined
     * behavior when evaluated. To improve user experience, this implementation
     * treats those the same way as {]. Any unclosed brackets, along with their
     * contents, or extraneous closing brackets are discarded.
     *
     * Custom operations:
     *
     *    {], {...] - Evaluates to 0. The inner expression, if any, is not
     *    evaluated. Can be used for comments, as long as opening brackets inside
     *    are balanced with an equal amount of closing brackets.
     *
     *    <) - Read a byte from standard input. Evaluates to -1 on EOF, -2 on error,
     *    and a positive integer (the byte) if successful.
     *
     *    <...) - If the inner expression evaluates to a non-negative value,
     *    truncate it to the size of a byte and write it to the standard output.
     *    Negative values cause undefined behavior, except -1 and -2 which close the
     *    standard output and input, respectively (does not actually work properly
     *    in this implementation as Rust doesn't have built-in constructs to do
     *    this). Evaluates to 0 on success, 1 on failure.
     */
    
    /*
     * Copyright (C)2023 Anonymous
     *
     * Permission is hereby granted, free of charge, to any person obtaining a copy
     * of this software and associated documentation files (the "Software"), to deal
     * in the Software without restriction, including without limitation the rights
     * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
     * copies of the Software, and to permit persons to whom the Software is
     * furnished to do so, subject to the following conditions:
     *
     * The above copyright notice and this permission notice shall be included in
     * all copies or substantial portions of the Software.
     *
     * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     * THE SOFTWARE.
     */
    
    mod brainflak {
        #[derive(Copy, Clone, PartialEq, Eq)]
        enum BracketType {
            Round,
            Square,
            Curly,
            Angle,
        }
        #[derive(Copy, Clone)]
        enum BracketSide {
            Opening,
            Closing,
        }
        #[derive(Copy, Clone)]
        struct Bracket {
            btype: BracketType,
            side: BracketSide,
        }
        use BracketSide::*;
        use BracketType::*;
        struct Func {
            btype: BracketType,
            monad: bool,
            addr: usize,
        }
        impl TryFrom<u8> for Bracket {
            type Error = ();
            fn try_from(c: u8) -> Result<Self, ()> {
                match c {
                    b'(' => Ok(Self {
                        btype: Round,
                        side: Opening,
                    }),
                    b'[' => Ok(Self {
                        btype: Square,
                        side: Opening,
                    }),
                    b'{' => Ok(Self {
                        btype: Curly,
                        side: Opening,
                    }),
                    b'<' => Ok(Self {
                        btype: Angle,
                        side: Opening,
                    }),
                    b')' => Ok(Self {
                        btype: Round,
                        side: Closing,
                    }),
                    b']' => Ok(Self {
                        btype: Square,
                        side: Closing,
                    }),
                    b'}' => Ok(Self {
                        btype: Curly,
                        side: Closing,
                    }),
                    b'>' => Ok(Self {
                        btype: Angle,
                        side: Closing,
                    }),
                    _ => Err(()),
                }
            }
        }
        pub struct Program {
            code: Box<[u8]>,
        }
        mod ops {
            pub const NOP: u8 = 0;
    
            pub const ONE: u8 = 1;
            pub const HEIGHT: u8 = 2;
            pub const POP: u8 = 3;
            pub const SWAP: u8 = 4;
    
            pub const NEW: u8 = 5;
            pub const PUSH: u8 = 6;
            pub const NEGATE: u8 = 7;
            pub const DROP: u8 = 8;
    
            pub const SAVE: u8 = 9;
            pub const ZRET: u8 = 10;
    
            pub const READ: u8 = 11;
            pub const WRITE: u8 = 12;
        }
        use ops::*;
        use std::io;
        use std::io::ErrorKind;
        use std::io::{Read, Write};
        use std::mem;
        impl Program {
            fn backtrack(code: &mut Vec<u8>, f: &Func) {
                code.truncate(f.addr);
            }
            pub fn run(&self, input: Vec<i64>, stdin: impl Read, stdout: impl Write) -> Vec<i64> {
                let mut active = input;
                let mut passive: Vec<i64> = Vec::new();
                let mut data: Vec<i64> = Vec::new();
                let mut rets: Vec<u32> = Vec::new();
                let mut exec: u32 = 0;
                let mut stdin = Some(stdin);
                let mut stdout = Some(stdout);
                let clen = self.code.len() as u32;
                while exec < clen {
                    let c = self.code[exec as usize];
                    match c {
                        SAVE | ZRET => match c {
                            SAVE => {
                                rets.push(exec + 5);
                                data.push(0);
                                exec = u32::from_le_bytes(
                                    self.code[((exec + 1) as usize)..((exec + 5) as usize)]
                                        .try_into()
                                        .unwrap(),
                                );
                            }
                            ZRET => {
                                if active.last().map(|v| *v).unwrap_or(0) != 0 {
                                    exec = *rets.last().unwrap();
                                } else {
                                    let v = data.pop().unwrap();
                                    data.last_mut().map(|pc| *pc += v);
                                    rets.pop().unwrap();
                                    exec += 1;
                                };
                            }
                            _ => unreachable!(),
                        },
                        NEW => {
                            data.push(0);
                            exec += 1;
                        }
                        NOP | ONE | HEIGHT | POP | SWAP | READ => {
                            let v = match c {
                                NOP => 0,
                                ONE => 1,
                                HEIGHT => active.len() as i64,
                                POP => active.pop().unwrap_or(0),
                                SWAP => {
                                    mem::swap(&mut active, &mut passive);
                                    0
                                }
                                READ => {
                                    let mut buffer = [0; 1];
                                    match stdin.as_mut() {
                                        Some(stdin) => match stdin.read_exact(&mut buffer) {
                                            Ok(_) => buffer[0] as i64,
                                            Err(e) => match e.kind() {
                                                ErrorKind::UnexpectedEof => -1,
                                                _ => -2,
                                            },
                                        },
                                        None => -2,
                                    }
                                }
                                _ => unreachable!(),
                            };
                            data.last_mut().map(|pc| *pc += v);
                            exec += 1;
                        }
                        PUSH | NEGATE | DROP | WRITE => {
                            let mut v = data.pop().unwrap();
                            match c {
                                PUSH => active.push(v),
                                NEGATE => v = -v,
                                DROP => v = 0,
                                WRITE => {
                                    v = match v {
                                        v if v >= 0 => match stdout.as_mut() {
                                            Some(stdout) => match stdout.write_all(&[v as u8]) {
                                                Ok(_) => 0,
                                                Err(_) => 1,
                                            },
                                            None => 1,
                                        },
                                        -1 => stdin.take().map_or(1, |_| 0),
                                        -2 => stdout.take().map_or(1, |_| 0),
                                        _ => 1,
                                    }
                                }
                                _ => unreachable!(),
                            }
                            data.last_mut().map(|pv| *pv += v);
                            exec += 1;
                        }
                        _ => panic!(),
                    }
                }
                active
            }
            pub fn new(file: impl Read) -> io::Result<Self> {
                let mut funcs: Vec<Func> = Vec::new();
                let mut code: Vec<u8> = Vec::new();
                for b in file.bytes().filter_map(|c| match c {
                    Ok(c) => Bracket::try_from(c).ok().map(|c| Ok(c)),
                    Err(e) => Some(Err(e)),
                }) {
                    let b = b?;
                    match b.side {
                        Opening => {
                            funcs.last_mut().map(|f| {
                                if f.monad {
                                    return;
                                }
                                f.monad = true;
                                if f.btype == Curly {
                                    code.extend([0; 4]);
                                }
                            });
                            funcs.push(Func {
                                btype: b.btype,
                                monad: false,
                                addr: code.len(),
                            });
                            code.push(0);
                        }
                        Closing => 'm: {
                            let f = if let Some(f) = funcs.pop() {
                                f
                            } else {
                                break 'm;
                            };
                            'e: {
                                match f.monad {
                                    false => {
                                        code[f.addr] = match (f.btype, b.btype) {
                                            (Round, Round) => ONE,
                                            (Square, Square) => HEIGHT,
                                            (Curly, Curly) => POP,
                                            (Angle, Angle) => SWAP,
                                            (Angle, Round) => READ,
                                            _ => break 'e Err(()),
                                        }
                                    }
                                    true => {
                                        if let (Curly, Curly) = (f.btype, b.btype) {
                                            code[f.addr] = SAVE;
                                            let addr = &(code.len() as u32).to_le_bytes();
                                            code[(f.addr + 1)..(f.addr + 5)].copy_from_slice(addr);
                                            code.push(ZRET);
                                        } else {
                                            code[f.addr] = NEW;
                                            code.push(match (f.btype, b.btype) {
                                                (Round, Round) => PUSH,
                                                (Square, Square) => NEGATE,
                                                (Angle, Angle) => DROP,
                                                (Angle, Round) => WRITE,
                                                _ => break 'e Err(()),
                                            });
                                        }
                                    }
                                }
                                Ok(())
                            }
                            .err()
                            .map(|_| Self::backtrack(&mut code, &f));
                        }
                    }
                    if code.len() > (u32::MAX as usize) {
                        panic!("Program too large");
                    }
                }
                funcs.first().map(|f| Self::backtrack(&mut code, &f));
                code.shrink_to_fit();
                Ok(Self {
                    code: code.into_boxed_slice(),
                })
            }
        }
    }
    
    pub use brainflak::*;
    use std::env;
    use std::fs::File;
    use std::io;
    use std::str::FromStr;
    
    fn main() {
        let mut args = env::args();
        args.next();
        let pfile = File::open(args.next().expect("invalid argument")).expect("failed to open file");
        let mut inputs = Vec::new();
        for p in args {
            inputs.push(i64::from_str(&p).expect("invalid argument"));
        }
        let program = Program::new(pfile).expect("fail");
        for i in program.run(inputs, io::stdin(), io::stdout()) {
            println!("{}", i);
        }
    }
    

    entry #4

    written by GNU Radio Shows
    submitted at
    4 likes

    guesses
    comments 0

    post a comment


    Flak.hs ASCII text
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    bf p i                                  = reverse (run 0 p [] [0] (reverse i) [])
    run 0 ('(':')':p)    r    (n:t)    m  a = run  0      p    r        ((n+1):t)    m  a
    run 0 ('[':']':p)    r    (n:t)    m  a = run  0      p    r ((n+length m):t)    m  a
    run 0 ('{':'}':p)    r    (n:t) (x:m) a = run  0      p    r        ((n+x):t)    m  a
    run 0 ('{':'}':p)    r       t     m  a = run  0      p    r               t     m  a
    run 0 ('<':'>':p)    r       t     m  a = run  0      p    r               t     a  m
    run 0     ('(':p)    r       t     m  a = run  0      p    r            (0:t)    m  a
    run 0     ('[':p)    r       t     m  a = run  0      p    r            (0:t)    m  a
    run o     ('{':p)    r       t     m  a = run (o+1)   p (p:r)           (0:t)    m  a
    run 0     ('<':p)    r       t     m  a = run  0      p    r            (0:t)    m  a
    run 0     (')':p)    r  (x:n:t)    m  a = run  0      p    r        ((n+x):t) (x:m) a
    run 0     (']':p)    r  (x:n:t)    m  a = run  0      p    r        ((n-x):t)    m  a
    run 0     ('>':p)    r    (_:t)    m  a = run  0      p    r               t     m  a
    run 0     ('}':p) (_:r) (x:n:t) (0:m) a = run  0      p    r        ((n+x):t) (0:m) a
    run 0     ('}':_) (p:r)      t     m  a = run  0      p (p:r)              t     m  a
    run 1     ('}':p)    r       t     m  a = run  0 ('}':p)   r               t     m  a
    run o     ('}':p) (_:r)   (_:t)    m  a = run (o-1)   p    r               t     m  a
    run o       (_:p)    r       t     m  a = run  o      p    r               t     m  a
    run _         []     _       _     m  _ = m
    

    entry #5

    written by ultlang
    submitted at
    1 like

    guesses
    comments 0

    post a comment


    cuessing.js Unicode text, UTF-8 text, with CRLF line terminators
      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
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    function entry(Source, Input){
    
    InputStack = Input // This is the "left stack", also known as the "stack not on the Right". Input goes here.
    kcatStupnI = []; // This is the "right stack", also known as the "stack on the Right". The evil twin of the input stack.
    Active = 1.0; // Left stack Active: 1 is at the Left of the decimal point.
    
    
    FormattedSource = Source.replace(/(\[\]|\(\)|{\}|\<>)/g, nilad => ({"()":"○","[]":"⎕","{}":"⍬","<>":"♢"}[nilad]));
    // APL symbols look good and Brain-Flak was simpler to implement this way to me.
    console.log(FormattedSource); // Bask in the glory of APL symbols.
    
    function run(Snippet) {
    	let Pointer = 0
    	let EValue = []; // Short for "evaluated value".
    
    	while (Pointer * Pointer != Math.pow(Snippet.length,2)) { // Are we done with the snippet?
    
    		switch (Snippet[Pointer]) {
    			case "○":
    				EValue.push(1);
    				break//
    			case "⎕":
    				EValue.push((Active==1.0?InputStack:kcatStupnI).length);
    				break//
    			case "⍬":
    				popped = (Active==1.0?InputStack:kcatStupnI).pop();
    				EValue.push(typeof popped == "undefined" ? 0 : popped); // According to the specification,
    				// Brain-Flak should return 0 if the active stack is empty.
    				break//
    			case "♢":
    				Active = (Active == 1.0 ? 0.1 : 1.0) // Toggles which stack is active.
    				EValue.push(0);
    				break//
    
    			case "(": {
    				let NestingLevel = 1
    				let EnclosedSnippet = ""
    				while (NestingLevel != 0) {
    					Pointer = Pointer + (Pointer?Pointer / Pointer:1)
    					EnclosedSnippet += Snippet[Pointer]
    					if (Snippet[Pointer] == "(") {NestingLevel += 1} else if
    					(Snippet[Pointer] == ")") {NestingLevel -= 1}
    				}
    
    				EnclosedSnippet = EnclosedSnippet.substring(0, EnclosedSnippet.length - 1);
    				result = run(EnclosedSnippet);
    				EValue.push(result);
    				(Active==1.0?InputStack:kcatStupnI).push(result);
    			}
    			;break//
    			
    			case "<": {
    				let NestingLevel = 1
    				let EnclosedSnippet = ""
    				while (NestingLevel != 0) {
    					Pointer = Pointer + (Pointer?Pointer / Pointer:1)
    					EnclosedSnippet += Snippet[Pointer]
    					if (Snippet[Pointer] == "<") {NestingLevel += 1} else if
    					(Snippet[Pointer] == ">") {NestingLevel -= 1}
    				}
    
    				EnclosedSnippet = EnclosedSnippet.substring(0, EnclosedSnippet.length - 1);
    				run(EnclosedSnippet)
    				EValue.push(0)
    			}
    			;break//
    	
    			case "{": {
    				let NestingLevel = 1
    				let EnclosedSnippet = ""
    				while (NestingLevel != 0) {
    					Pointer = Pointer + (Pointer?Pointer / Pointer:1)
    					EnclosedSnippet += Snippet[Pointer]
    					if (Snippet[Pointer] == "{") {NestingLevel += 1} else if
    					(Snippet[Pointer] == "}") {NestingLevel -= 1}
    				}
    
    				EnclosedSnippet = EnclosedSnippet.substring(0, EnclosedSnippet.length - 1);
    				let EValueInCurlyBraces = []
    				while ((Active==1.0?InputStack:kcatStupnI)[(Active==1.0?InputStack:kcatStupnI).length-1] != 0
    				       || (Active==1.0?InputStack:kcatStupnI).length == 0) {
    					EValueInCurlyBraces.push(run(EnclosedSnippet))
    				}
    				EValue.push( EValueInCurlyBraces.reduce((x, y) => x+y, 0))
    			
    			}
    			;break//
    
    			case "[": {
    				let NestingLevel = 1
    				let EnclosedSnippet = ""
    				while (NestingLevel != 0) {
    					Pointer = Pointer + (Pointer?Pointer / Pointer:1)
    					EnclosedSnippet += Snippet[Pointer]
    					if (Snippet[Pointer] == "[") {NestingLevel += 1} else if
    					(Snippet[Pointer] == "]") {NestingLevel -= 1}
    				}
    
    				EnclosedSnippet = EnclosedSnippet.substring(0, EnclosedSnippet.length - 1);
    				EValue.push(0 - run(EnclosedSnippet))
    			}
    			;break//
    		}
    	
    		Pointer = Pointer + (Pointer?Pointer / Pointer:1) // There is probably no better way to increment a variable.
    	}
    	let evalue_final_FINAL_jpg = EValue.reduce((x, y) => x+y, 0)
    	return evalue_final_FINAL_jpg;
    }
    
    run(FormattedSource)
    console.log(Active==1.0?InputStack:kcatStupnI) // Shows the active stack.
    return (Active==1.0?InputStack:kcatStupnI)
    }
    
    /*
    // Example program from the Esolangs wiki.
    // This program computes [number on the stack not on the Right] steps of the Fibonacci sequence.
    entry("<>((()))<>{({}[()])<>({}<>)<>(({})<>({}<>))<>}<>{}{}", [50]);
    */
    
    json.py.rs.html.rtf.exe.com.tar.gz.txt ASCII text, with CRLF line terminators
    1
    2
    3
    4
    5
    6
    7
    8
     (((( ]]]] <<<< }}}}}
    ((   ]]  ]]<< <<}}
    ((   ]]  ]]<< <<}}}}
     (((( ]]]] <<<< }}}}}
     ))))[[  [[>>>>> {{{{
    ))   [[  [[>>   {{
    )) ))[[  [[>>>>    {{
     )))) [[[[ >>>>>{{{{sing
    

    entry #6

    written by olus2000
    submitted at
    1 like

    guesses
    comments 0

    post a comment


    brain-flak.tar.bz3 bzip3 compressed data, blocksize 16777216
    dir brain-flak
    authors.txt ASCII text
    1
    // Code by SoundOfSpouting#6980 (UID: 151149148639330304)
    
    brain-flak-docs.factor ASCII text, with very long lines (411)
      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
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    ! // Code by SoundOfSpouting#6980 (UID: 151149148639330304)
    ! See http://factorcode.org/license.txt for BSD license.
    USING: help.markup help.syntax kernel strings urls ;
    IN: brain-flak
    
    HELP: unclosed-brain-flak-expression
    { $values
      { "program" object }
    }
    { $description "Throws an " { $link unclosed-brain-flak-expression } " error." }
    { $error-description "Thrown during brain-flak compilation if an opened subexpression doesn't have a closing bracket."
    } ;
    
    HELP: mismatched-brain-flak-brackets
    { $values
      { "program" object } { "character" object }
    }
    { $description "Throws an " { $link mismatched-brain-flak-brackets } " error." }
    { $error-description "Thrown if a bracket is closed with a bracket that doesn't match." } ;
    
    HELP: leftover-program-after-compilation
    { $values
      { "program" object } { "leftover" object }
    }
    { $description "Throws an " { $link leftover-program-after-compilation } " error." }
    { $error-description "Thrown if excessive closing brackets are encountered during compilation." } ;
    
    
    HELP: b-f"
    { $syntax "b-f\"({}[]){<>()}\"" }
    { $description "Syntax for a brain-flak program. It will take a sequence, run the program with the sequence as the initial active stack, and replace the sequence with the final active stack. Syntax and semantics of brain-flak are explained in" { $link "brain-flak" } .
    }
    { $errors "Throws an error when the parsed string is not a correct brain-flak program" }
    { $examples
      { $example
        "USING: brain-flak prettyprint ;"
        "{ 2 1 3 7 } b-f\"({{}})\" ."
        "{ 13 }"
      }
      { $example
        "USING: brain-flak prettyprint ;"
        "{ 1 2 } b-f\"(({}({}))[({}[{}])])\" ."
        "{ 2 1 }"
      }
    }
    { $see-also compile-brain-flak } ;
    
    HELP: compile-brain-flak
    { $values
      { "string" string }
      { "quote" { $quotation ( seq -- seq ) } }
    }
    { $description
      "Compiles a brain-flak program in" { $snippet "string" } "into a quotation that can be run on a sequence of numbers and will return a sequence of numbers. Syntax and semantics of brain-flak are explained in" { $link "brain-flak" } "."
    }
    { $errors "Throws an error when the string is not a correct brain-flak program" }
    { $examples
      { $example
        "USING: brain-flak kernel prettyprint ;"
        "\"({{}})\" compile-brain-flak"
        "{ 2 1 3 7 } swap call( seq -- seq ) ."
        "{ 13 }"
      }
      { $example
        "USING: brain-flak kernel prettyprint ;"
        "\"(({}({}))[({}[{}])])\" compile-brain-flak"
        "{ 1 2 } swap call( seq -- seq ) ."
        "{ 2 1 }"
      }
    }
    { $see-also \ b-f" } ;
    
    ARTICLE: "brain-flak" "Introduction to brain-flak"
    { { $url URL"https://esolangs.org/wiki/Brain-Flak" "Brain-flak" } " is a stack-based esoteric language designed by Programming Puzzles and Code-Golf user " { $url URL"https://codegolf.stackexchange.com/users/31716/djmcmayhem" "DjMcMayhem" } } . The name is a cross between "\"brainfuck\"" , which was a big inspiration for the language, and "\"flak-overstow\"" , since the language is confusing and stack-based.
    
    { $heading "Overview" }
    Brain-flak is an expression-based language written only using brackets, which must be balanced. Any other character will be ignored. Its only data type is a signed integer, which in this implementation has unbounded size.
    { $nl }
    There are two stacks, one of which is considered the { $strong "active" } stack at each point of the execution. Programs start with the active stack initialised with the input data and inactive stack empty, and return the active stack when finished. Popping from an empty stack yields 0.
    { $nl }
    Each expression in brain-flak executes some side-effects on the stacks and evaluates to a number. Concatenation of expressions performs their side-effects from left to right and evaluates to a sum of their evaluations.
    
    { $heading "Functions" }
    There are two types of functions in brain-flak: nilads, that are brackets without any contents, and monads, which are non-empty bracketed subexpressions.
    { $nl }
    Nilads:
    { $list
      { { $snippet "()" } " evaluates to 1" }
      { { $snippet "[]" } " evaluates to the height of the active stack" }
      { { $snippet "{}" } " pops the active stack and evaluates to the popped value" }
      { { $snippet "<>" } " swaps active and inactive stack and evaluates to 0" }
    }
    Recall that concatenating expressions sums their values, so { $snippet "()()()" } will evaluate to 3, and { $snippet "{}()" } will pop from the active stack and evaluate to one more than the popped value.
    { $nl }
    Monads:
    { $list
      { { $snippet "(X)" } " evaluates " { $snippet "X" } ", pushes the result on the stack and evaluates to the same value" }
      { { $snippet "[X]" } " evaluates " { $snippet "X" } " and evaluates to its negation" }
      { { $snippet "{X}" } " evaluates " { $snippet "X" } " in a loop as long as top of the active stack is not 0 and evaluates to the sum of all results" }
      { { $snippet "<X>" } " evaluates " { $snippet "X" } ", discards the result and evaluates to zero" }
    }
    For example program { $snippet "([(()()())])" } will push numbers 3 and -3 to the stack, and program { $snippet "({{}})" } will replace values on the stack until a zero with their sum.
    
    { $examples "Examples of brain-flak programs can be seen on its " { $url URL"https://github.com/DJMcMayhem/Brain-Flak/wiki/Stack-Operations" "github wiki" } "." }
    
    { $heading "Vocabulary" }
    The { $vocab-link "brain-flak" } vocabulary provides a brain-flak to Factor compiler in two words: { $subsections compile-brain-flak POSTPONE: b-f" } These offer a way to compile brain-flak strings into quotations and embed them directly in code. Programs compiled this way will take a sequence for their initial active stack and return a sequence of the same type representing the "final" active stack.
    ;
    
    ABOUT: "brain-flak"
    
    brain-flak-tests.factor 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
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    ! // Code by SoundOfSpouting#6980 (UID: 151149148639330304)
    ! See http://factorcode.org/license.txt for BSD license.
    USING: accessors brain-flak combinators.short-circuit kernel
        strings tools.test ;
    IN: brain-flak.tests
    
    
    { { } } [ { } "" compile-brain-flak call ] unit-test
    
    { { } } [ { } b-f"" ] unit-test
    
    { { } } [ { } "X" compile-brain-flak call ] unit-test
    
    { { } } [ { } b-f"X" ] unit-test
    
    { { } } [ { } "()" compile-brain-flak call ] unit-test
    
    { { } } [ { } b-f"()" ] unit-test
    
    { { } } [ { } "[]" compile-brain-flak call ] unit-test
    
    { { } } [ { } b-f"[]" ] unit-test
    
    { { } } [ { } "{}" compile-brain-flak call ] unit-test
    
    { { } } [ { } b-f"{}" ] unit-test
    
    { { } } [ { } "<>" compile-brain-flak call ] unit-test
    
    { { } } [ { } b-f"<>" ] unit-test
    
    { { 1 } } [ { } "(())" compile-brain-flak call ] unit-test
    
    { { 1 } } [ { } b-f"(())" ] unit-test
    
    { { 1 } } [ { } "((X))" compile-brain-flak call ] unit-test
    
    { { 1 } } [ { } b-f"((X))" ] unit-test
    
    { { 1 } } [ { } "(X()X)" compile-brain-flak call ] unit-test
    
    { { 1 } } [ { } b-f"(X()X)" ] unit-test
    
    { { 2 } } [ { } "(()())" compile-brain-flak call ] unit-test
    
    { { 2 } } [ { } b-f"(()())" ] unit-test
    
    { { 2 2 } } [ { } "((()()))" compile-brain-flak call ] unit-test
    
    { { 2 2 } } [ { } b-f"((()()))" ] unit-test
    
    { { 0 } } [ { } "([])" compile-brain-flak call ] unit-test
    
    { { 0 } } [ { } b-f"([])" ] unit-test
    
    { { 1 2 3 3 } } [ { 1 2 3 } "([])" compile-brain-flak call ] unit-test
    
    { { 1 2 3 3 } } [ { 1 2 3 } b-f"([])" ] unit-test
    
    { { 1 2 2 3 } } [ { 1 2 } "([])([])" compile-brain-flak call ] unit-test
    
    { { 1 2 2 3 } } [ { 1 2 } b-f"([])([])" ] unit-test
    
    { { 0 } } [ { } "({})" compile-brain-flak call ] unit-test
    
    { { 0 } } [ { } b-f"({})" ] unit-test
    
    { { 1 2 } } [ { 1 2 } "({})" compile-brain-flak call ] unit-test
    
    { { 1 2 } } [ { 1 2 } b-f"({})" ] unit-test
    
    { { 1 } } [ { 1 2 } "{}" compile-brain-flak call ] unit-test
    
    { { 1 } } [ { 1 2 } b-f"{}" ] unit-test
    
    { { 0 } } [ { 1 2 } "(<>)" compile-brain-flak call ] unit-test
    
    { { 0 } } [ { 1 2 } b-f"(<>)" ] unit-test
    
    { { 1 2 0 } } [ { 1 2 } "(<><>)" compile-brain-flak call ] unit-test
    
    { { 1 2 0 } } [ { 1 2 } b-f"(<><>)" ] unit-test
    
    { { 0 } } [ { } "([[]])" compile-brain-flak call ] unit-test
    
    { { 0 } } [ { } b-f"([[]])" ] unit-test
    
    { { 1 2 -2 } } [ { 1 2 } "([[]])" compile-brain-flak call ] unit-test
    
    { { 1 2 -2 } } [ { 1 2 } b-f"([[]])" ] unit-test
    
    { { 0 } } [ { } "([()]())" compile-brain-flak call ] unit-test
    
    { { 0 } } [ { } b-f"([()]())" ] unit-test
    
    { { 0 } } [ { } "({<>})" compile-brain-flak call ] unit-test
    
    { { 0 } } [ { } b-f"({<>})" ] unit-test
    
    { { 4 3 2 1 0 6 } } [ { 4 } "({(({})[()])})" compile-brain-flak call ] unit-test
    
    { { 4 3 2 1 0 6 } } [ { 4 } b-f"({(({})[()])})" ] unit-test
    
    { { 0 } } [ { } "(<()()()>)" compile-brain-flak call ] unit-test
    
    { { 0 } } [ { } b-f"(<()()()>)" ] unit-test
    
    { { 1 0 } } [ { 1 2 } "(<<>({}())>)" compile-brain-flak call ] unit-test
    
    { { 1 0 } } [ { 1 2 } b-f"(<<>({}())>)" ] unit-test
    
    
    [ "{" compile-brain-flak call ]
    [ { [ unclosed-brain-flak-expression? ]
        [ program>> "{" = ]
      } 1&&
    ] must-fail-with
    
    [ "{>" compile-brain-flak call ]
    [ { [ mismatched-brain-flak-brackets? ]
        [ program>> "{>" = ]
      } 1&&
    ] must-fail-with
    
    [ "{}>" compile-brain-flak call ]
    [ { [ leftover-program-after-compilation? ]
        [ program>> "{}>" = ]
        [ leftover>> >string ">" = ]
      } 1&&
    ] must-fail-with
    
    brain-flak.factor 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
    ! // Code by SoundOfSpouting#6980 (UID: 151149148639330304)
    ! See http://factorcode.org/license.txt for BSD license.
    USING: accessors assocs combinators combinators.short-circuit
        kernel math sequences sets splitting strings.parser vectors
    ;
    IN: brain-flak
    
    
    << ALIAS: ' CHAR: >>
    
    
    ERROR: unclosed-brain-flak-expression program ;
    ERROR: mismatched-brain-flak-brackets program ;
    ERROR: leftover-program-after-compilation program leftover ;
    
    
    <PRIVATE
    
    : matches ( a b -- ? )
      { { ' ( ' ) }
        { ' [ ' ] }
        { ' { ' } }
        { ' < ' > }
        { ' ) ' ( }
        { ' ] ' [ }
        { ' } ' { }
        { ' > ' < }
      } at =
    ;
    
    : glue ( a stack2 stack1 b -- a+b stack2 stack1 ) roll + -rot ;
    
    : (()) ( ret stack2 stack1 -- ret stack2 stack1 ) 1 glue ;
    
    : ([]) ( ret stack2 stack1 -- ret stack2 stack1 ) dup length glue ;
    
    : ({}) ( ret stack2 stack1 -- ret stack2 stack1 ) dup [ pop glue ] unless-empty ;
    
    : (<>) ( ret stack2 stack1 -- ret stack2 stack1 ) swap ;
    
    : ()) ( ret stack2 stack1 quot -- ret stack2 stack1 ) 0 -roll call rot [ suffix! ] keep glue ; inline
    
    : (]) ( ret stack2 stack1 quot -- ret stack2 stack1 ) 0 -roll call rot neg glue ; inline
    
    : (}) ( ret stack2 stack1 quot -- ret stack2 stack1 ) 0 -roll [ dup { [ empty? ] [ last 0 = ] } 1|| ] swap until rot glue ; inline
    
    : (>) ( ret stack2 stack1 quot -- ret stack2 stack1 ) 0 -roll call rot drop ; inline
    
    : compile-bf-subexpr ( vec string-like -- vec string-like )
      [ { { [ dup empty? ] [ f ] }
          { [ dup first ")]}>" in? ] [ f ] }
          { [ "()" ?head-slice ] [ [ \ (()) suffix! ] dip t ] }
          { [ "[]" ?head-slice ] [ [ \ ([]) suffix! ] dip t ] }
          { [ "{}" ?head-slice ] [ [ \ ({}) suffix! ] dip t ] }
          { [ "<>" ?head-slice ] [ [ \ (<>) suffix! ] dip t ] }
          [ 0 <vector> swap [ rest-slice ] [ first ] bi
            [ compile-bf-subexpr [ [ ] clone-like suffix! ] dip
              [ dup empty?
                [ dup seq>> unclosed-brain-flak-expression ]
                [ rest-slice ] if ] [ ?first ] bi
            ] dip
            over matches
            [ over seq>> mismatched-brain-flak-brackets ] unless
            { { ' ) [ [ \ ()) suffix! ] dip ] }
              { ' ] [ [ \ (]) suffix! ] dip ] }
              { ' } [ [ \ (}) suffix! ] dip ] }
              { ' > [ [ \ (>) suffix! ] dip ] }
            } case t
          ]
        } cond
      ] loop
    ;
    
    PRIVATE>
    
    
    : compile-brain-flak ( string -- quote )
      [ "()[]{}<>" in? ] filter dup
      V{ dup V{ } clone-like 0 0 <vector> rot } clone
      swap compile-bf-subexpr
      [ overd leftover-program-after-compilation ] unless-empty
      { 2nip swap clone-like } append! [ ] clone-like nip
    ;
    
    SYNTAX: b-f" parse-string compile-brain-flak append! ;
    
    summary.txt ASCII text
    1
    A Brain-flak to Factor compiler
    
    tags.txt ASCII text
    1
    2
    3
    4
    brain-flak
    languages
    parsing
    syntax
    

    entry #7

    written by razetime
    submitted at
    1 like

    guesses
    comments 0

    post a comment


    pane_flak.py ASCII text, with very long lines (3630)
      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
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    # Brain-flak interpreter in Python
    # soon to be added: proper debugging capability
    # Flakhead society approved
    
    def read_until_matching(s, start):
        stack_height = 0
        for idx, char in enumerate(s[start + 1 :]):
            match char:
                case "{":
                    stack_height += 1
                case "}":
                    stack_height -= 1
                    if stack_height == -1:
                        return idx + start + 1
        return False
    
    
    class Interpreter:
        left = []
        right = []
        main = []
        active = left
        index = 0
        current_value = 0
        running = False
    
        def reset(self):
            self.left = []
            self.right = []
            self.main = []
            self.active = self.left
            self.index = 0
            self.current_value = 0
            self.running = False
    
        def __init__(self, source):
            self.source = source
    
        def step(self):
            if not self.running:
                return False
    
            is_nilad = True
            match self.source[self.index : self.index + 2]:
                case "()":
                    self.current_value += 1
                case "[]":
                    self.current_value += len(self.active)
                case "{}":
                    if self.active:
                        self.current_value += self.active.pop()
                case "<>":
                    self.active = self.right if self.active == self.left else self.left
                case _:
                    is_nilad = False
            if is_nilad:
                self.index += 2
            else:
                match self.source[self.index]:
                    case "(":
                        self.main.append(("(", self.current_value, self.index))
                        self.current_value = 0
                    case "[":
                        self.main.append(("[", self.current_value, self.index))
                        self.current_value = 0
                    case "{":
                        self.main.append(("{", 0, self.index))
                        new_index = read_until_matching(self.source, self.index)
                        if not self.active or self.active[-1] == 0:
                            self.main.pop()
                            self.index = new_index
                    case "<":
                        self.main.append(("<", self.current_value, self.index))
                        self.current_value = 0
                    case ")":
                        _, inc, _ = self.main.pop()
                        self.active.append(self.current_value)
                        self.current_value += inc
                    case "]":
                        _, inc, _ = self.main.pop()
                        self.current_value *= -1
                        self.current_value += inc
                    case "}":
                        _, inc, idx = self.main.pop()
                        self.index = idx - 1
                        self.current_value += inc
                    case ">":
                        _, inc, _ = self.main.pop()
                        self.current_value = inc
                self.index += 1
    
            if self.index >= len(self.source):
                self.running = False
    
            return True
    
        def run(self, input):
            self.reset()
            self.left = input
            self.active = self.left
            self.running = True
            while self.running:
                self.step()
            return self.active
    
    
    for code, input in [
        ("(([]){[{}]{}([])}{})", [5, 69, 700, 8214]),  # sum stack
        ("({}{})", [0x12, 123]),  # add two numbers
        ("(())", []),  # 1
        ("<>((()))<>{({}[()])<>({}<>)<>(({})<>({}<>))<>}<>{}{}", [9]),  # Fibonacci
        # ('(()()()()()()())(())(()()()()()()())(()()()()()()()())(()()())(()()()())(()())(()()())(()()()())(()()()()()()()())(()()())(()()()())(())(()()()()())(()()()()()())(()())(()()()()()()())(())(()()()()()()())(()()()()()()()())(()()()()())(())(()())(()()()()()())(()()())(())(())(()()()()())(()()()()()()())(()()()()()()()())(()()()()()())(())(()())(()()())(())(())(())(())(())(())(())(())(())(()())(())(()())(())(()())(())(()())(())(()())(()())(()()()()()()())(()()()()()()()())(()())(()()()()()()())(()()()()()()()())(()())(()()()()()()())(()()()()()()()())(()())(()()())(()()()())(()())(()())(())(()())(()())(()())(()()()())(()())(()()())(()()()())(()())(()()()()()()())(())(()()()()()()())(()()()()()()()())(())(()())(()()())(())(()()()()()()())(()()()()()()()())(())(()())(()())(()()()())(()())(()()()()()()())(())(()()()()()()())(()()()()()()()())(())(()())(()()())(())(()()()()()()())(()()()()()()()())(())(())(())(())(()())(())(()())(())(()())(()())(()())(()()()()()()())(()()()()()()()())(()()()()()()())(()()()()()()()())(()())(()()()()()()())(()()()()()()()())(())(()())(()())(()()()())(()())(()()()()()()())(())(()()()()()()())(()()()()()()()())(())(()())(()()())(())(()()()()()()())(()()()()()()()())(())(()())(())(()())(()())(()()()())(()())(()()()()()()())(())(()()()()()()())(()()()()()()()())(())(()())(()()())(())(()()()()()()())(()()()()()()()())(())(())(())(())(()())(())(()())(())(()())(()())(()()()()()()())(()()()()()()()())(())(()())(()())(()()()()()()())(()()()()()()()())(()())(()()()()()()())(()()()()()()()())(())(()())(()())(()()()())(()())(()()()()()()())(())(()()()()()()())(()()()()()()()())(())(()())(()()())(())(()()()()()()())(()()()()()()()())(())(()())(())(()())(()())(()()()())(()())(()()()()()()())(())(()()()()()()())(()()()()()()()())(())(()())(()()())(())(()()()()()()())(()()()()()()()())(())(())(())(())(()())(())(()())(())(()())(())(()())(())(()())(()())(()())(()()()()()()())(()()()()()()()())(()()()()()()())(()()()()()()()())(()())(()()()()()()())(()()()()()()()())(()())(()()()())(()())(()()()()()()())(())(()()())(()()()()()()())(()()()()()()()())(())(()()()()()()())(()()()()()()()())(())(()())(())(()())(()())(()()()())(()())(()()()()()()()())(()()()()()()()())(()()()()()()()())(()()()()()()()())(()()()()()()()())(()()()()()()()())(()()()()()()()())(()()()()()()())(()()()()()()()())(())(()()()()())(()()()()()())(()()())(())(()()()()()()())(()()()()()()()())(()()())(()()()()()()())(())(()()()()()()())(()()()()()()()())(()()())(()()()())(()())(()()())(()()()())(()()()()()()()())(()()())(()()()())(()()()())(()())(()()()())(()())(()()()()()()())(())(()()()()()()())(()()()()()()()())(()()()()())(())(()())(()()()()()())(()()())(())(()()()()()()())(()()()()()()()())(()()())(()()()())(()())(()()())(()()()())(()()()())(()())(()()()()()()()())(()()()()()()())(()()()()()()()())(()()()()()()())(())(()()()()()()())(()()()()()()()())(())(()())(()()())(())(())(())(()()()()()()())(()()()()()()()())(()()()()())(())(()())(()()()()()())(()())(())(()())(()())(()())(()()()())(()())(()()()()()()()())(()()()()()()())(()()()()()()()())(()()())(()()()())(()()()())(()())(()()()()()()()())(()()()()()()())(()()()()()()()())(()()()()()()())(()()())(()()()())(())(()()()()()()())(()()()()()()()())(()()())(()()()())(()())(()()()()()()()()){({}<>)<>}<>([]){({}[()]<(([{}]()<((((((((()()()()()){}){}){})<>))()))>)<>){({}()<({}())>){({}()<({}(((()()())){}{}){}())>){({}()<({}()())>){({}()<({}(((()()()){}()){}){}())>){({}()<({}()())>){({}()<({}(((()()()()())){}{}){})>){(<{}({}()())>)}}}}}}}{}([]<({}<{({}<>)<>}<>>)>){({}[()]<({}<>)<>>)}{}{({}()<((({}[()])()))>)}{}<>>)}{}{<>({}<>)}', [])
    ]:
        print(Interpreter(code).run(input))
    

    entry #8

    written by Olivia
    submitted at
    5 likes

    guesses
    comments 1
    jan Metu

    hi!


    post a comment


    hi!.hs 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
    {-# LANGUAGE LambdaCase #-} {-# LANGUAGE OverloadedStrings #-} {--                                                    ##                        --}
    import Text.Megaparsec (parse, errorBundlePretty, between, choice, many, sepBy, Parsec, eof) {--                      ##       ##               --}
    {--                              --} ; import Control.Lens ((<&>), uncons, uses, (%=), (.=), _1) {--                 ##      ##     ###         --}
    {--       ######                           --} ; import Text.Megaparsec.Char (char, newline, space1) {--             ##### ###         ###      --}
    {--    ####    ##        #####                 --} ; import Text.Megaparsec.Char.Lexer (decimal, signed) {--        ##   ####           ## #### --}
    {--  ###               ##    ###    ###                         --} ; import Control.Monad.State (execState) {--  ##       ##         ##        --}
    {-- ##               ##       ##    ## ##    ##                            --} ; import Data.Maybe (listToMaybe) {--      ##         ##         --}
    {--##               ##        ##   ##   ##   #######             #####          --} ; import Control.Monad.Fix (fix) {--       ###  ##          --}
    {--##              ##        ##   ##    ##   ##     ####       ###    ###            --} ; import Data.Text (pack, Text) {--     #####          --}
    {-- ##             ##       ##   ##     ##   ##              ##         ##   ##               --} ; import Data.Tuple (swap) {--     ####     ##--}
    {--  ###     ##    ##     ##   ##      ##   #####          ##               ##                     --} ; import Data.Void (Void) {--         ## --}
    {--     ####        #####     ##     ##    ##             ##      ###      ##         ##               --} ; import Data.Bool (bool) {--    #   --}
    {--                            ######     ##              ##        ###   ##         ##    ###              --} ; data T = P | B | C | A {--    --}
    {--                                     ######            ##        ##    ##        ##    ##  ####                    --} ; data F = F T [F] {----}
    main = getContents >>= ((\case {--          ######         ###   ###     ##         ##   ##      ###                                            --}
    {--} Left e -> putStrLn $ errorBundlePretty {--              ####        ##        ##   ##           ######                                     --}
    {--   --} e; Right (f, i) -> (putStrLn . unwords {--                      ###    ##    ######      ###    ##    ####                            --}
    {--        --} . (show <$>) . reverse . fst) (execState {--                 #####     ##    ##    ##       #  ##   ###                          --}
    {--             --} (fix (\x -> foldl (\a f -> a >>= (\n -> ( {--                   ###           ##         ##      ##                         --}
    {--                  --} n +) <$> (\(F t p) -> if null p then case {--             ######           ###     ##            ##                    --}
    {--         ##            --} t of P -> return 1 ; B -> uses _1 length {--              ####  ##      ##     ##          ##   ##                --}
    {--         ##        ##       --} C -> uses _1 uncons >>= maybe (return 0) {--                ##    ##        ###      ##   ###   ##           --}
    {-- #####  ##       ##              --} (\(h, t) -> _1 .= t >> return h); A -> {--              #####    #       ##     ##  ####  ##     ###### --}
    {--    #########   ##        ######      --} id %= swap >> return 0 else case t of{--                    ###    ##     ##  ##  ## ##   ##    ###--}
    {--      ##    ########            ###        --} P -> x p >>= (\n -> _1 %= (n :) >> return {--           ######      ##   ##  ###   ##        #--}
    {--     ##       ##                  ##            --} n); B -> negate <$> x p; C -> fix (\l f -> {--               ###   ##   ##   ##   ###    --}
    {-- ### ##      ##                   ##     ######      --} uses _1 ((0 `elem`) . listToMaybe) >>= bool {--        ##    ##    ##   ##     ###  --}
    {--   ######   ###          ###    ##     ##     ###         --} (x f >>= (\n -> (n +) <$> l f)) (return 0)) {--              ##    ##    ##    --}
    {--   ##    ##########         ####      ##       ##    ####      --} p; A -> x p >> return 0) f)) (return 0)) f) {--                #####      --}
    {--  ##       ##                  ##     ###      ##    ###   ####     --} (reverse i, []))) . parse ((,) <$> many (fix {--                     --}
    {--  ##      ###       ##         ##        #######    ###    ###           --} (\t -> choice $ zipWith3 between (char <$> {--                  --}
    {-- ##       ##        ####     ###   #          ##    ##     ##                 --} "([{<") (char <$> ")]}>") ((many t <&>) . {--              --}
    {--         ##            ######      ###       ##    ##     ##                       --} F <$> [P, B, C, A]))) <* newline <*> signed {--       --}
    {--                                     ########                                           --} (pure ()) decimal `sepBy` space1 <* eof :: {--   --}
    {--                                                 ###    ##                                   --} Parsec Void Text ([F], [Int])) "") . pack {---}
    

    entry #9

    written by luatic
    submitted at
    0 likes

    guesses
    comments 0

    post a comment


    cg39.scm 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
    ; Brain-Flak implementation in Chicken Scheme for Code Guessing Round 39
    ; Supports line comments using `#`, ignores invalid characters
    ; Compilation & invocation: `csc cg39.scm && ./cg39 FILE [ARGS ...]`
    (import (chicken process-context))
    (define (parse port)
      (define (paren closing)
        (read-char port)
        (let ((sub (parse port)))
          (assert (eqv? (read-char port) closing))
          (cons
           (cons closing sub)
           (parse port))))
      (let ((c (peek-char port)))
        (case c
          ((#\) #\] #\} #\> #!eof) '())
          ((#\() (paren #\)))
          ((#\[) (paren #\]))
          ((#\{) (paren #\}))
          ((#\<) (paren #\>))
          (else
           (if (eqv? (read-char port) #\#)
               (do () ((memv (read-char port) '(#\newline #!eof)))))
           (parse port)))))
    (define (exec exp active)
      (let ((inactive '()))
        (define (pop)
          (if (null? active) 0
            (let ((top (car active))) (set! active (cdr active)) top)))
        (define (push x)
          (set! active (cons x active)))
        (define (toggle)
          (let ((a active)) (set! active inactive) (set! inactive a)))
        (define (ctx-eval exp)
          (if (null? exp) 0
              (let ((sub (cdr exp)) (nilad (null? (cdr exp))))
                (if (list? (car exp))
                    (apply + (map ctx-eval exp))
                    (case (car exp)
                      ((#\)) (if nilad 1 (let ((k (ctx-eval sub))) (push k) k)))
                      ((#\]) (if nilad (length active) (- (ctx-eval sub))))
                      ((#\}) (if nilad (pop)
                           (do ((sum 0))
                               ((or (null? active) (= (car active) 0)) sum)
                             (set! sum (+ sum (ctx-eval sub))))))
                      ((#\>) (begin (if nilad (toggle) (ctx-eval sub)) 0)))))))
        (ctx-eval exp))
      (for-each (lambda (x) (display x) (newline)) active))
    (let ((args (command-line-arguments)))
      (call-with-input-file (car args)
        (lambda (port)
          (let ((exp (parse port)))
            (assert (eof-object? (read-char port)))
            (exec exp (map string->number (reverse (cdr args))))))))
    

    entry #10

    written by soup girl
    submitted at
    1 like

    guesses
    comments 0

    post a comment


    ^_^.png PNG image data, 307 x 180, 8-bit/color RGBA, non-interlaced
    flak.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
    86
    87
    88
    89
    function toggle(s, t, c)
       return c(0, t, s)
    end
    
    function one(s, t, c)
       return c(1, s, t)
    end
    
    function height(s, t, c)
       return c(#s, s, t)
    end
    
    function void(n)
       return function (s, t, c)
          return n(s, t, function (x, y, z)
             return c(0, y, z)
          end)
       end
    end
    
    function neg(n)
       return function (s, t, c)
          return n(s, t, function (x, y, z)
             return c(-x, y, z)
          end)
       end
    end
    
    function pop(s, t, c)
       local u = {}
       for i = 2, #s do
          u[i-1] = s[i]
       end
       return c(s[1], u, t)
    end
    
    function loop(n)
       return function (s, t, c)
          if #s == 0 or s[1] == 0 then
             return c(0, s, t)
          else
             return concat(n, loop(n))(s, t, c)
          end
       end
    end
    
    function concat(m, n)
       return function (s, t, c)
          return m(s, t, function (x, y, z)
             return n(y, z, function (p, q, r)
                return c(x+p, q, r)
             end)
          end)
       end
    end
    
    function push(n)
       return function (s, t, c)
          return n(s, t, function (x, y, z)
             local u = {x}
             for i = 1, #y do
                u[i+1] = y[i]
             end
             return c(x, u, z)
          end)
       end
    end
    
    function parse(f, s, c)
       local nilads = { ['()']=one, ['[]']=height, ['{}']=pop, ['<>']=toggle }
       local monads = { ['(']=push, ['[']=neg, ['{']=loop, ['<']=void }
       local nilad = nilads[string.sub(s, 1, 2)]
       local monad = monads[string.sub(s, 1, 1)]
       if nilad then
          return parse(concat(f, nilad), string.sub(s, 3), c)
       elseif monad then
          return parse(void(one), string.sub(s, 2), function (g, s)
             return parse(concat(f, monad(g)), string.sub(s, 2), c)
          end)
       else
          return c(f, s)
       end
    end
    
    function brainflak(s, n)
       s = string.gsub(s, "[^%[%](){}<>]", "")
       s, t = parse(void(one), s, function (f, s) return f, s end)
       return s(n, {}, function (x, y, z) return y end)
    end
    

    entry #11

    written by taswelll
    submitted at
    3 likes

    guesses
    comments 0

    post a comment


    entry.nix 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
    with builtins; rec {
      parse = 
        with (import (fetchTarball {
          url = "https://github.com/kanwren/nix-parsec/archive/v0.2.0.tar.gz";
          sha256 = "1v1krqzvpmb39s42m5gg2p7phhp4spd0vkb4wlhfkgbhi20dk5w7";
        })).parsec;
        let {
          spaces = void (many (choice [
            (string " ") (string "\n") (skipThen (string "#") (skipWhile (c: c != "\n")))
          ]));
          symbol = s: thenSkip (string s) spaces;
          br = open: close:
            lift2 (b: c: {inherit b c;}) (symbol open) (thenSkip expr (symbol close));
          expr = many (choice [ (br "(" ")") (br "[" "]") (br "{" "}") (br "<" ">") ]);
          body = runParser (between spaces eof expr);
        };
      eval = s1: s2:
        let
          init   = l: genList (x: elemAt l x) (length l - 1);
          last   = l: elemAt l (length l - 1);
          return = s1: s2: ret: { inherit s1 s2 ret; };
          toRet  = f: v: v//{ ret = f v.ret; };
          eval1  = s1: s2: expr:
            (if length expr.c == 0 then {
              ${"("} = return s1 s2 1;
              ${"["} = return s1 s2 (length s1);
              ${"<"} = return s2 s1 0;
              ${"{"} = if s1 == [] then return s1 s2 0 else return (init s1) s2 (last s1);
            } else {
              ${"("} = (v: v//{ s1=v.s1++[v.ret]; }) (eval s1 s2 expr.c);
              ${"["} = (toRet (x: -x)) (eval s1 s2 expr.c);
              ${"<"} = (toRet (x: 0 )) (eval s1 s2 expr.c);
              ${"{"} = let loop = {s1, s2, ret}@v:
                if s1 == [] || last s1 == 0 then v else (toRet (x: x+ret)) (loop (eval s1 s2 expr.c));
              in loop (return s1 s2 0);
            }).${expr.b};
        in foldl'
          ({s1, s2, ret}: next: (toRet (x: x+ret)) (eval1 s1 s2 next))
          (return s1 s2 0);
      run = stack: code: with parse code;
        if type == "success" then eval stack [] value else throw (toJSON value);
    }
    

    entry #12

    written by Palaiologos
    submitted at
    1 like

    guesses
    comments 0

    post a comment


    cg39 ELF 64-bit LSB executable, x86-64, version 1 (SYSV)
    cg39.hint Unicode text, UTF-8 text
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    -*-mode:text;coding:utf-8-*-
    
    $ uname -m
    x86_64
    $ ./cg39 "((()()())(()()()()){{}})"
    7
    
    どのように機能するのでしょうか?
    
    Handle input with:
    
    import sys
    import os
    p=sys.argv[1]
    k=lambda x:"(("+o(x//3)+")){}{}"+(x%3)*"()"if x>3 else"()"*x
    m=lambda x:"("+o(x//2)+"){}"+(x%2)*"()"if x>6 else"()"*x
    o=lambda x:min(k(x),m(x),key=len)
    i=sys.stdin.read()
    i=i[:-1] if i[-1]=='\n' else i
    r=''.join(["("+o(ord(c))+")"for c in i])+p
    os.system("./cg39 '%s'"%r)