2016 Update
This commit is contained in:
parent
948b86eafa
commit
dcf5d15da3
7965 changed files with 139854 additions and 31002 deletions
|
|
@ -1,4 +1,6 @@
|
|||
{{implementation|Brainf***}}RCBF is a set of [[Brainf***]] compilers and interpreters written for Rosetta Code in a variety of languages. <br>
|
||||
{{implementation|Brainf***}}
|
||||
RCBF is a set of [[Brainf***]] compilers and interpreters written for Rosetta Code in a variety of languages.
|
||||
|
||||
Below are links to each of the versions of RCBF.
|
||||
|
||||
An implementation need only properly implement the following instructions:
|
||||
|
|
@ -22,5 +24,5 @@ An implementation need only properly implement the following instructions:
|
|||
|-
|
||||
| style="text-align:center"| <code>]</code> || Jump back to the matching <code>[</code> if the cell under the pointer is nonzero
|
||||
|}
|
||||
Any cell size is allowed, EOF support is optional, as is whether you have bounded or unbounded memory.
|
||||
<br>
|
||||
Any cell size is allowed, EOF (<u>E</u>nd-<u>O</u>-<u>F</u>ile) support is optional, as is whether you have bounded or unbounded memory.
|
||||
<br><br>
|
||||
|
|
|
|||
76
Task/Execute-Brain----/Fortran/execute-brain-----1.f
Normal file
76
Task/Execute-Brain----/Fortran/execute-brain-----1.f
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
MODULE BRAIN !It will suffer.
|
||||
INTEGER MSG,KBD
|
||||
CONTAINS !A twisted interpreter.
|
||||
SUBROUTINE RUN(PROG,STORE) !Code and data are separate!
|
||||
CHARACTER*(*) PROG !So, this is the code.
|
||||
CHARACTER*(1) STORE(:) !And this a work area.
|
||||
CHARACTER*1 C !The code of the moment.
|
||||
INTEGER I,D !Fingers to an instruction, and to data.
|
||||
D = 1 !First element of the store.
|
||||
I = 1 !First element of the prog.
|
||||
|
||||
DO WHILE(I.LE.LEN(PROG)) !Off the end yet?
|
||||
C = PROG(I:I) !Load the opcode fingered by I.
|
||||
I = I + 1 !Advance one. The classic.
|
||||
SELECT CASE(C) !Now decode the instruction.
|
||||
CASE(">") !Move the data finger one place right.
|
||||
D = D + 1
|
||||
CASE("<") !Move the data finger one place left.
|
||||
D = D - 1
|
||||
CASE("+") !Add one to the fingered datum.
|
||||
STORE(D) = CHAR(ICHAR(STORE(D)) + 1)
|
||||
CASE("-") !Subtract one.
|
||||
STORE(D) = CHAR(ICHAR(STORE(D)) - 1)
|
||||
CASE(".") !Write a character.
|
||||
WRITE (MSG,1) STORE(D)
|
||||
CASE(",") !Read a character.
|
||||
READ (KBD,1) STORE(D)
|
||||
CASE("[") !Conditionally, surge forward.
|
||||
IF (ICHAR(STORE(D)).EQ.0) CALL SEEK(+1)
|
||||
CASE("]") !Conditionally, retreat.
|
||||
IF (ICHAR(STORE(D)).NE.0) CALL SEEK(-1)
|
||||
CASE DEFAULT !For all others,
|
||||
!Do nothing.
|
||||
END SELECT !That was simple.
|
||||
END DO !See what comes next.
|
||||
|
||||
1 FORMAT (A1,$) !One character, no advance to the next line.
|
||||
CONTAINS !Now for an assistant.
|
||||
SUBROUTINE SEEK(WAY) !Look for the BA that matches the AB.
|
||||
INTEGER WAY !Which direction: ±1.
|
||||
CHARACTER*1 AB,BA !The dancers.
|
||||
INTEGER INDEEP !Nested brackets are allowed.
|
||||
INDEEP = 0 !None have been counted.
|
||||
I = I - 1 !Back to where C came from PROG.
|
||||
AB = PROG(I:I) !The starter.
|
||||
BA = "[ ]"(WAY + 2:WAY + 2) !The stopper.
|
||||
1 IF (I.GT.LEN(PROG)) STOP "Out of code!" !Perhaps not!
|
||||
IF (PROG(I:I).EQ.AB) THEN !A starter? (Even if backwards)
|
||||
INDEEP = INDEEP + 1 !Yep.
|
||||
ELSE IF (PROG(I:I).EQ.BA) THEN !A stopper?
|
||||
INDEEP = INDEEP - 1 !Yep.
|
||||
END IF !A case statement requires constants.
|
||||
IF (INDEEP.GT.0) THEN !Are we out of it yet?
|
||||
I = I + WAY !No. Move.
|
||||
IF (I.GT.0) GO TO 1 !And try again.
|
||||
STOP "Back to 0!" !Perhaps not.
|
||||
END IF !But if we are out of the nest,
|
||||
I = I + 1 !Advance to the following instruction, either WAY.
|
||||
END SUBROUTINE SEEK !Seek, and one shall surely find.
|
||||
END SUBROUTINE RUN !So much for that.
|
||||
END MODULE BRAIN !Simple in itself.
|
||||
|
||||
PROGRAM POKE !A tester.
|
||||
USE BRAIN !In a rather bad way.
|
||||
CHARACTER*1 STORE(30000) !Probably rather more than is needed.
|
||||
CHARACTER*(*) HELLOWORLD !Believe it or not...
|
||||
PARAMETER (HELLOWORLD = "++++++++[>++++[>++>+++>+++>+<<<<-]"
|
||||
1 //" >+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------"
|
||||
2 //".--------.>>+.>++.")
|
||||
KBD = 5 !Standard input.
|
||||
MSG = 6 !Standard output.
|
||||
STORE = CHAR(0) !Scrub.
|
||||
|
||||
CALL RUN(HELLOWORLD,STORE) !Have a go.
|
||||
|
||||
END !Enough.
|
||||
103
Task/Execute-Brain----/Fortran/execute-brain-----2.f
Normal file
103
Task/Execute-Brain----/Fortran/execute-brain-----2.f
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
SUBROUTINE BRAINFORT(PROG,N,INF,OUF,F) !Stand strong!
|
||||
Converts the Brain*uck in PROG into the equivalent furrytran source...
|
||||
CHARACTER*(*) PROG !The Brain*uck source.
|
||||
INTEGER N !A size for the STORE.
|
||||
INTEGER INF,OUF,F !I/O unit numbers.
|
||||
INTEGER L !A stepper.
|
||||
INTEGER LABEL,NLABEL,INDEEP,STACK(66) !Labels cause difficulty.
|
||||
CHARACTER*1 C !The operation of the moment.
|
||||
CHARACTER*36 SOURCE !A scratchpad.
|
||||
WRITE (F,1) PROG,N !The programme heading.
|
||||
1 FORMAT (6X,"PROGRAM BRAINFORT",/, !Name it.
|
||||
1 "Code: ",A,/ !Show the provenance.
|
||||
2 6X,"CHARACTER*1 STORE(",I0,")",/ !Declare the working memory.
|
||||
3 6X,"INTEGER D",/ !The finger to the cell of the moment.
|
||||
4 6X,"STORE = CHAR(0)",/ !Clear to nulls, not spaces.
|
||||
5 6X,"D = 1",/) !Start the data finger at the first cell.
|
||||
NLABEL = 0 !No labels seen.
|
||||
INDEEP = 0 !So, the stack is empty.
|
||||
LABEL = 0 !And the current label is absent.
|
||||
L = 1 !Start at the start.
|
||||
Chug through the PROG.
|
||||
DO WHILE(L.LE.LEN(PROG)) !And step through to the end.
|
||||
C = PROG(L:L) !The code of the moment.
|
||||
SELECT CASE(C) !What to do?
|
||||
CASE(">") !Move the data finger forwards one.
|
||||
WRITE (SOURCE,2) "D = D + ",RATTLE(">") !But, catch multiple steps.
|
||||
CASE("<") !Move the data finger back one.
|
||||
WRITE (SOURCE,2) "D = D - ",RATTLE("<") !Rather than a sequence of one steps.
|
||||
CASE("+") !Increment the fingered datum by one.
|
||||
WRITE (SOURCE,2) "STORE(D) = CHAR(ICHAR(STORE(D)) + ", !Catching multiple increments.
|
||||
1 RATTLE("+"),")" !And being careful over the placement of brackets.
|
||||
CASE("-") !Decrement the fingered datum by one.
|
||||
WRITE (SOURCE,2) "STORE(D) = CHAR(ICHAR(STORE(D)) - ", !Catching multiple decrements.
|
||||
1 RATTLE("-"),")" !And closing brackets.
|
||||
CASE(".") !Write a character.
|
||||
WRITE (SOURCE,2) "WRITE (",OUF,",'(A1,$)') STORE(D)" !Using the given output unit.
|
||||
CASE(",") !Read a charactger.
|
||||
WRITE (SOURCE,2) "READ (",INF,",'(A1)') STORE(D)" !And the input unit.
|
||||
CASE("[") !A label!
|
||||
NLABEL = NLABEL + 1 !Labels come in pairs due to [...]
|
||||
LABEL = 2*NLABEL - 1 !So this belongs to the [.
|
||||
INDEEP = INDEEP + 1 !I need to remember when later the ] is encountered.
|
||||
STACK(INDEEP) = LABEL + 1 !This will be the other label.
|
||||
WRITE (SOURCE,2) "IF (ICHAR(STORE(D)).EQ.0) GO TO ", !So, go thee, therefore.
|
||||
1 STACK(INDEEP) !Its placement will come, all going well.
|
||||
CASE("]") !The end of a [...] pair.
|
||||
LABEL = STACK(INDEEP) !This was the value of the label to be, now to be placed.
|
||||
WRITE (SOURCE,2) "IF (ICHAR(STORE(D)).NE.0) GO TO ", !The conditional part
|
||||
1 LABEL - 1 !The branch back destination is known by construction.
|
||||
INDEEP = INDEEP - 1 !And we're out of the [...] sequence's consequences.
|
||||
CASE DEFAULT !All others are ignored.
|
||||
SOURCE = "CONTINUE" !So, just carry on.
|
||||
END SELECT !Enough of all that.
|
||||
2 FORMAT (A,I0,A) !Text, an integer, text.
|
||||
Cast forth the statement.
|
||||
IF (LABEL.LE.0) THEN !Is a label waiting?
|
||||
WRITE (F,3) SOURCE !No. Just roll the source.
|
||||
3 FORMAT (<6 + 2*MIN(12,INDEEP)>X,A)!With indentation.
|
||||
ELSE !But if there is a label,
|
||||
WRITE (F,4) LABEL,SOURCE !Slightly more complicated.
|
||||
4 FORMAT (I5,<1 + 2*MIN(12,INDEEP)>X,A) !I align my labels rightwards...
|
||||
LABEL = 0 !It is used.
|
||||
END IF !So much for that statement.
|
||||
L = L + 1 !Advance to the next command.
|
||||
END DO !And perhaps we're finished.
|
||||
|
||||
Closedown.
|
||||
WRITE (F,100) !No more source.
|
||||
100 FORMAT (6X,"END") !So, this is the end.
|
||||
CONTAINS !A function with odd effects.
|
||||
INTEGER FUNCTION RATTLE(C) !Advances thrugh multiple C, counting them.
|
||||
CHARACTER*1 C !The symbol.
|
||||
RATTLE = 1 !We have one to start with.
|
||||
1 IF (L.LT.LEN(PROG)) THEN !Further text to look at?
|
||||
IF (PROG(L + 1:L + 1).EQ.C) THEN !Yes. The same again?
|
||||
L = L + 1 !Yes. Advance the finger to it.
|
||||
RATTLE = RATTLE + 1 !Count another.
|
||||
GO TO 1 !And try again.
|
||||
END IF !Rather than just one at a time.
|
||||
END IF !Curse the double evaluation of WHILE(L < LEN(PROG) & ...)
|
||||
END FUNCTION RATTLE !Computers excel at counting.
|
||||
END SUBROUTINE BRAINFORT!They only need be direction as to what to count...
|
||||
END MODULE BRAIN !Simple in itself.
|
||||
|
||||
PROGRAM POKE !A tester.
|
||||
USE BRAIN !In a rather bad way.
|
||||
CHARACTER*1 STORE(30000) !Probably rather more than is needed.
|
||||
CHARACTER*(*) HELLOWORLD !Believe it or not...
|
||||
PARAMETER (HELLOWORLD = "++++++++[>++++[>++>+++>+++>+<<<<-]"
|
||||
1 //" >+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------"
|
||||
2 //".--------.>>+.>++.")
|
||||
INTEGER F
|
||||
KBD = 5 !Standard input.
|
||||
MSG = 6 !Standard output.
|
||||
F = 10
|
||||
|
||||
STORE = CHAR(0) !Scrub.
|
||||
|
||||
c CALL RUN(HELLOWORLD,STORE) !Have a go.
|
||||
|
||||
OPEN (F,FILE="BrainFort.for",STATUS="REPLACE",ACTION="WRITE")
|
||||
CALL BRAINFORT(HELLOWORLD,30000,KBD,MSG,F)
|
||||
END !Enough.
|
||||
68
Task/Execute-Brain----/Fortran/execute-brain-----3.f
Normal file
68
Task/Execute-Brain----/Fortran/execute-brain-----3.f
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
PROGRAM BRAINFORT
|
||||
Code: ++++++++[>++++[>++>+++>+++>+<<<<-] >+>+>->>+[<]<-]>>.>---.+++++++..+++.>>.<-.<.+++.------.--------.>>+.>++.
|
||||
CHARACTER*1 STORE(30000)
|
||||
INTEGER D
|
||||
STORE = CHAR(0)
|
||||
D = 1
|
||||
|
||||
STORE(D) = CHAR(ICHAR(STORE(D)) + 8)
|
||||
1 IF (ICHAR(STORE(D)).EQ.0) GO TO 2
|
||||
D = D + 1
|
||||
STORE(D) = CHAR(ICHAR(STORE(D)) + 4)
|
||||
3 IF (ICHAR(STORE(D)).EQ.0) GO TO 4
|
||||
D = D + 1
|
||||
STORE(D) = CHAR(ICHAR(STORE(D)) + 2)
|
||||
D = D + 1
|
||||
STORE(D) = CHAR(ICHAR(STORE(D)) + 3)
|
||||
D = D + 1
|
||||
STORE(D) = CHAR(ICHAR(STORE(D)) + 3)
|
||||
D = D + 1
|
||||
STORE(D) = CHAR(ICHAR(STORE(D)) + 1)
|
||||
D = D - 4
|
||||
STORE(D) = CHAR(ICHAR(STORE(D)) - 1)
|
||||
4 IF (ICHAR(STORE(D)).NE.0) GO TO 3
|
||||
CONTINUE
|
||||
D = D + 1
|
||||
STORE(D) = CHAR(ICHAR(STORE(D)) + 1)
|
||||
D = D + 1
|
||||
STORE(D) = CHAR(ICHAR(STORE(D)) + 1)
|
||||
D = D + 1
|
||||
STORE(D) = CHAR(ICHAR(STORE(D)) - 1)
|
||||
D = D + 2
|
||||
STORE(D) = CHAR(ICHAR(STORE(D)) + 1)
|
||||
5 IF (ICHAR(STORE(D)).EQ.0) GO TO 6
|
||||
D = D - 1
|
||||
6 IF (ICHAR(STORE(D)).NE.0) GO TO 5
|
||||
D = D - 1
|
||||
STORE(D) = CHAR(ICHAR(STORE(D)) - 1)
|
||||
2 IF (ICHAR(STORE(D)).NE.0) GO TO 1
|
||||
D = D + 2
|
||||
WRITE (6,'(A1,$)') STORE(D)
|
||||
D = D + 1
|
||||
STORE(D) = CHAR(ICHAR(STORE(D)) - 3)
|
||||
WRITE (6,'(A1,$)') STORE(D)
|
||||
STORE(D) = CHAR(ICHAR(STORE(D)) + 7)
|
||||
WRITE (6,'(A1,$)') STORE(D)
|
||||
WRITE (6,'(A1,$)') STORE(D)
|
||||
STORE(D) = CHAR(ICHAR(STORE(D)) + 3)
|
||||
WRITE (6,'(A1,$)') STORE(D)
|
||||
D = D + 2
|
||||
WRITE (6,'(A1,$)') STORE(D)
|
||||
D = D - 1
|
||||
STORE(D) = CHAR(ICHAR(STORE(D)) - 1)
|
||||
WRITE (6,'(A1,$)') STORE(D)
|
||||
D = D - 1
|
||||
WRITE (6,'(A1,$)') STORE(D)
|
||||
STORE(D) = CHAR(ICHAR(STORE(D)) + 3)
|
||||
WRITE (6,'(A1,$)') STORE(D)
|
||||
STORE(D) = CHAR(ICHAR(STORE(D)) - 6)
|
||||
WRITE (6,'(A1,$)') STORE(D)
|
||||
STORE(D) = CHAR(ICHAR(STORE(D)) - 8)
|
||||
WRITE (6,'(A1,$)') STORE(D)
|
||||
D = D + 2
|
||||
STORE(D) = CHAR(ICHAR(STORE(D)) + 1)
|
||||
WRITE (6,'(A1,$)') STORE(D)
|
||||
D = D + 1
|
||||
STORE(D) = CHAR(ICHAR(STORE(D)) + 2)
|
||||
WRITE (6,'(A1,$)') STORE(D)
|
||||
END
|
||||
2
Task/Execute-Brain----/Fortran/execute-brain-----4.f
Normal file
2
Task/Execute-Brain----/Fortran/execute-brain-----4.f
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
4 IF (ICHAR(STORE(D)).NE.0) GO TO 3
|
||||
IF (ICHAR(STORE(D)).NE.0) GO TO 3
|
||||
|
|
@ -1,52 +1,55 @@
|
|||
/*REXX program to implement the Brainf*ck (self-censored) language. */
|
||||
#.=0 /*initialize the infinite "tape".*/
|
||||
p=0 /*the "tape" cell pointer. */
|
||||
!=0 /* ! is the instruction pointer.*/
|
||||
parse arg $ /*allow CBLF to specify a BF pgm.*/
|
||||
/* │ No pgm? Then use default.*/
|
||||
if $='' then $=, /* ↓ displays: Hello, World! */
|
||||
"++++++++++ initialize cell #0 to 10; then loop: ",
|
||||
"[ > +++++++ add 7 to cell #1; final result: 70 ",
|
||||
" > ++++++++++ add 10 to cell #2; final result: 100 ",
|
||||
" > +++ add 3 to cell #3; final result 30 ",
|
||||
" > + add 1 to cell #4; final result 10 ",
|
||||
" <<<< - ] decrement cell #0 ",
|
||||
"> ++ . display 'H' which is ASCII 72 (decimal) ",
|
||||
"> + . display 'e' which is ASCII 101 (decimal) ",
|
||||
"+++++++ .. display 'll' which is ASCII 108 (decimal) {2}",
|
||||
"+++ . display 'o' which is ASCII 111 (decimal) ",
|
||||
"> ++ . display ' ' which is ASCII 32 (decimal) ",
|
||||
"<< +++++++++++++++ . display 'W' which is ASCII 87 (decimal) ",
|
||||
"> . display 'o' which is ASCII 111 (decimal) ",
|
||||
"+++ . display 'r' which is ASCII 114 (decimal) ",
|
||||
"------ . display 'l' which is ASCII 108 (decimal) ",
|
||||
"-------- . display 'd' which is ASCII 100 (decimal) ",
|
||||
"> + . display '!' which is ASCII 33 (decimal) "
|
||||
/*(above) note Brainf*ck comments*/
|
||||
do forever; !=!+1; if !==0 | !>length($) then leave; x=substr($,!,1)
|
||||
select /*examine the current instruction*/
|
||||
when x=='+' then #.p=#.p + 1 /*increment the "tape" cell by 1.*/
|
||||
when x=='-' then #.p=#.p - 1 /*decrement the "tape" cell by 1.*/
|
||||
when x=='>' then p=p + 1 /*increment the pointer by 1.*/
|
||||
when x=='<' then p=p - 1 /*decrement the pointer by 1.*/
|
||||
when x=='[' then != forward() /*go forward to ]+1 if #.P =0.*/
|
||||
when x==']' then !=backward() /*go backward to [+1 if #.P ¬0.*/
|
||||
when x=='.' then call charout ,d2c(#.p) /*display a "tape" cell.*/
|
||||
when x==',' then do; say 'input a value:'; parse pull #.p; end
|
||||
/*REXX program implements the Brainf*ck (self─censored) language. */
|
||||
@.=0 /*initialize the infinite "tape". */
|
||||
p =0 /*the "tape" cell pointer. */
|
||||
! =0 /* ! is the instruction pointer (IP).*/
|
||||
parse arg $ /*allow user to specify a BrainF*ck pgm*/
|
||||
/* ┌──◄── No program? Then use default;*/
|
||||
if $='' then $=, /* ↓ it displays: Hello, World! */
|
||||
"++++++++++ initialize cell #0 to 10; then loop: ",
|
||||
"[ > +++++++ add 7 to cell #1; final result: 70 ",
|
||||
" > ++++++++++ add 10 to cell #2; final result: 100 ",
|
||||
" > +++ add 3 to cell #3; final result 30 ",
|
||||
" > + add 1 to cell #4; final result 10 ",
|
||||
" <<<< - ] decrement cell #0 ",
|
||||
"> ++ . display 'H' which is ASCII 72 (decimal) ",
|
||||
"> + . display 'e' which is ASCII 101 (decimal) ",
|
||||
"+++++++ .. display 'll' which is ASCII 108 (decimal) {2}",
|
||||
"+++ . display 'o' which is ASCII 111 (decimal) ",
|
||||
"> ++ . display ' ' which is ASCII 32 (decimal) ",
|
||||
"<< +++++++++++++++ . display 'W' which is ASCII 87 (decimal) ",
|
||||
"> . display 'o' which is ASCII 111 (decimal) ",
|
||||
"+++ . display 'r' which is ASCII 114 (decimal) ",
|
||||
"------ . display 'l' which is ASCII 108 (decimal) ",
|
||||
"-------- . display 'd' which is ASCII 100 (decimal) ",
|
||||
"> + . display '!' which is ASCII 33 (decimal) "
|
||||
/* [↑] note the Brainf*ck comments.*/
|
||||
do !=1 while !\==0 & !<=length($) /*keep executing BF as long as IP ¬ 0*/
|
||||
parse var $ =(!) x +1 /*obtain a Brainf*ck instruction (x),*/
|
||||
/*···it's the same as x=substr($,!,1) */
|
||||
select /*examine the current instruction. */
|
||||
when x=='+' then @.p=@.p + 1 /*increment the "tape" cell by 1 */
|
||||
when x=='-' then @.p=@.p - 1 /*decrement " " " " " */
|
||||
when x=='>' then p= p + 1 /*increment " instruction ptr " " */
|
||||
when x=='<' then p= p - 1 /*decrement " " " " " */
|
||||
when x=='[' then != forward() /*go forward to ]+1 if @.P = 0. */
|
||||
when x==']' then !=backward() /* " backward " [+1 " " ¬ " */
|
||||
when x== . then call charout , d2c(@.p) /*display a "tape" cell to terminal. */
|
||||
when x==',' then do; say 'input a value:'; parse pull @.p; end
|
||||
otherwise iterate
|
||||
end /*select*/
|
||||
end /*forever*/
|
||||
exit /*stick a fork in it, we're done.*/
|
||||
/*──────────────────────────────────FORWARD subroutine──────────────────*/
|
||||
forward: if #.p\==0 then return !; c=1 /* C is the [ nested counter.*/
|
||||
do k=!+1 to length($); z=substr($,k,1)
|
||||
if z=='[' then do; c=c+1; iterate; end
|
||||
if z==']' then do; c=c-1; if c==0 then leave; end
|
||||
end /*k*/
|
||||
return k
|
||||
/*──────────────────────────────────BACKWARD subroutine─────────────────*/
|
||||
backward: if #.p==0 then return !; c=1 /* C is the ] nested counter.*/
|
||||
do k=!-1 to 1 by -1; z=substr($,k,1)
|
||||
if z==']' then do; c=c+1; iterate; end
|
||||
if z=='[' then do; c=c-1; if c==0 then return k+1; end
|
||||
end /*k*/
|
||||
exit /*stick a fork in it, we're all done. */
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
forward: if @.p\==0 then return !; c=1 /*C: ◄─── is the [ nested counter.*/
|
||||
do k=!+1 to length($); ?=substr($, k, 1)
|
||||
if ?=='[' then do; c=c+1; iterate; end
|
||||
if ?==']' then do; c=c-1; if c==0 then leave; end
|
||||
end /*k*/
|
||||
return k
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
backward: if @.p==0 then return !; c=1 /*C: ◄─── is the ] nested counter.*/
|
||||
do k=!-1 to 1 by -1; ?=substr($, k, 1)
|
||||
if ?==']' then do; c=c+1; iterate; end
|
||||
if ?=='[' then do; c=c-1; if c==0 then return k+1; end
|
||||
end /*k*/
|
||||
return k
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue