루프 본문을 건너 뛸 때 BASIC이 비 순차적 NEXT 문을 찾는 방법


9

WABAC 머신 , 셔먼을 설정하십시오 . 이 질문은 일반적으로 BASIC, 특히 Microsoft의 BASIC-80 에 관한 것입니다. 올드 스쿨 기본. 줄 번호와 함께.

루프 본문이 실행되지 않았을 때 구식 BASIC 인터프리터가 FOR ... NEXT 루프를 어떻게 처리하고 NEXT 문이 순서대로 나타나지 않았습니까?

이전 시간의 비 순차적 NEXT 문 :

다음 은 David H. Ahl의 "101 Basic Computer Games"에서 Awari 게임의 서브 루틴입니다 .

200 K=M:GOSUB 600
205 E=0:IF K>6 THEN K=K-7
210 C=C+1:IF C<9 THEN F(N)=F(N)*6+K
215 FOR I=0 TO 5:IF B(I)<>0 THEN 230
220 NEXT I
225 RETURN
230 FOR I=7 TO 12:IF B(I)<>0 THEN E=1:RETURN
235 GOTO 220

흐름 제어를 제외한 모든 것이 수정되었습니다.

200 GOSUB 600
215 FOR I=0 TO 5:IF ... THEN 230
220 NEXT I
225 RETURN
230 FOR I=7 TO 12:IF ... THEN RETURN
235 GOTO 220

그것이 그렇게 좋지 않은 기억을 되 찾는가? 그의 무덤에서 Dijkstra가 전복되는 것을들을 수 있습니까 ?

이 조각에서 일어나는 일의 흥미로운 부분은 다음과 같습니다.

  • 두 번째 FOR 루프는 동일한 루프 변수를 사용하므로 첫 번째 FOR 루프를 대체합니다.
  • 두 개의 FOR 루프는 동일한 NEXT 문을 공유합니다.
  • 두 번째 FOR 루프의 NEXT 문은 소스 순서로, 그 뒤에는 실행 순서로옵니다.

그러면 FOR 루프를 시작한 인터프리터가 NEXT 루프에서 발생할 때까지 명령문을 실행한다고 가정 할 수 있습니다. 이 경우 소스의 진술 순서는 중요하지 않습니다. 그러나 FOR 루프에 대해 basic80 매뉴얼에서 무엇을 말해야하는지 보자.

basic-80 매뉴얼은 "moo ..."라고 말합니다.

단계의 부호에 루프의 초기 값이 단계의 부호에 대한 최종 값의 시간을 초과하면 루프의 본문이 생략됩니다.

따라서 루프 본문을 완전히 건너 뛸 수 있습니다.

우리는 출판 된 프로그램의 형태로, 적어도 일부 버전의 BASIC이 그들의 NEXT 문장을 동적으로 찾는다는 증거를 가지고 있습니다. 루프 바디가 실행될 때 쉽게 할 수 있습니다. 그러나 BASIC-80이 허용하는 것처럼 FOR 문의 본문을 건너 뛰어야하는 경우 BASIC 은 소스 문에서 FOR 문 앞에 있을 수 있다는 점을 고려하여 NEXT 문을 어떻게 찾 습니까?

  • "101 기본 컴퓨터 게임"에 사용 된 BASIC 버전은 항상 루프 본문을 한 번 이상 실행 했습니까?
  • BASIC-80은 소스 순서대로 FOR 문 다음에 FOR 루프의 NEXT 문이 필요합니까?

추신 : 예, 저는 구식 BASIC을위한 BASIC 통역사를 쓰고 있습니다. 병입니다.


Ahl 책은 원래 1973 년 DEC에 의해 출판되어 Microsoft BASIC보다 2 년 앞서 있습니다. 프로그램은 아마도 RT-11 BASIC 또는 BASIC-PLUS에서 수행되었을 것입니다. 시스템 별 확장명 외에 대부분의 방언이 호환되었으며, 몇 가지 시스템에서 DEC 버전의 도서 프로그램을 거의 또는 전혀 어려움없이 실행했습니다. Applesoft BASIC ROM을 밝게 분해하여 문서화 한 소스 를 찾을 수 있습니다 . NEXT명령문 을 구현하는 코드 는 $ DCF9에서 시작합니다.
Blrfl

BASIC-80에 대해 모르지만 Commodore Basic (Microsoft BASIC V2)은 항상 루프를 한 번 실행하고 소스의 문장 순서는 중요하지 않습니다.
Doc Brown

답변:


7

이것은 옛날을 되찾아줍니다 ...

1975 년 제 3 회 인쇄 된 책의 사본이 있습니다. 목록을 확인했으며 원본이 아닙니다. 원래 소스 코드에서 명령문에는 공백이 없으며 할당에는 키워드 LET이 있습니다. 예를 들어

200 LETK=M:GOSUB600

방언은 DIGITAL PDP-11 BASIC (Basic-plus 또는 BASIC-80 아님)입니다. 경험상이 게임들이 BASIC의 모든 방언에서 작동하지는 않았습니다. 다른 방언으로 작업하기 위해 이러한 게임 중 일부를 다시 코딩해야한다는 모호한 기억이 있습니다. 이런 종류의 끔찍한 루프 구조는 분명히 문제였습니다.

나는 20 가지가 넘는 BASIC의 방언을 경험 한 적이 있는데 이것이 당시에 변덕스러운 질문이었다고 말할 수 있습니다. 2 개의 주요 캠프가 있었다.

한 캠프에는 완전한 통역사가 있었는데, 각 통역사가 보일 때마다 각 줄을 새롭게 분석했습니다. 그들은 FOR 루프를 스택에 밀어 넣고 변수로 식별 한 다음 스택을 스캔하여 각 NEXT와 일치하는지 확인했습니다. 루프를 건너 뛴 경우 소스를 NEXT로 스캔해야합니다. 어떤 사람들은 그렇지 않았습니다.

다른 캠프는 토크 나이 저나 세미 컴파일러였습니다. 그들은 실행하기 전에 모든 줄을 스캔하여 일종의 내부 형식으로 변환합니다. 또한 FOR / NEXT 루프와 일치하고 누락 된 GOTO 및 GOSUB 대상이 있는지 확인했습니다. 내가 기억 하듯이 DEC와 BASIC-80은이 캠프에 있었지만 오래 전입니다.

귀하의 질문에 대한 답변으로

  1. 예, BASIC의 방언은 처음에 만족하면 루프를 건너 뜁니다.
  2. 아니요, FOR NEXT의 시퀀싱은 문서화 된 요구 사항은 아니지만 동작은 정의되지 않았습니다. 전문가로서 나는 결코 그것을 한 적이 없다. :)

도움이 되었기를 바랍니다. 이것들은 끔찍한 언어이지만, 당신이해야한다면 ...


매우 도움이됩니다. 감사합니다. 이 책에는 DEC 버전, TRS-80 버전 및 마이크로 컴퓨터 버전이 있습니다. 마이크로 컴퓨터 버전의 프로그램은 Microsoft 8080 기본 (MITS Altair Basic Rev 4.0)에 있습니다. 그것이 나의 통역사의 목표입니다.
Wayne Conrad

1980 년경에는 CP / M에서 MBASIC을 사용했지만 이전의 취미 시스템은 없었습니다. 파일 시스템이 필요합니다! 여러 가지면에서 DEC / DG / HP / CAI / Prime / Interdata / Tektronix Basic의 환생이 더 흥미 롭다는 것을 알았지 만 그 이유가 무엇인지 이해할 수 있습니다. 행운을 빌어 요! 도움이 필요하면 연락하십시오.
david.pfx

2

나는이 고대 BASIC 통역사 중 하나에 대한 사양의 사본을 가지고 있지 않지만 (존재하지 않을 수도 있음), 사지로 나가서 BASIC 통역사가 루프 변수의 이름이 같은 경우에도 속하지 않는 FOR 루프의 NEXT .

다시 말해, 당신의 예에서

200 K=M:GOSUB 600
205 E=0:IF K>6 THEN K=K-7
210 C=C+1:IF C<9 THEN F(N)=F(N)*6+K
215 FOR I=0 TO 5:IF B(I)<>0 THEN 230
220 NEXT I
225 RETURN
230 FOR I=7 TO 12:IF B(I)<>0 THEN E=1:RETURN
235 GOTO 220

라인 (235)이 실행되고 라인 (220)으로 갈 때, 라인 (220) 은 맨 아래가 아니라 맨 위 FOR 루프 다음에있을 것이다.

"포스트없이 다음"오류 메시지에 나타납니다. BASIC 인터프리터는 해당 FOR를 찾지 못한 NEXT를 거부합니다. 이것은 일반적으로 다음과 같이 NEXT가 고장난 경우에 발생합니다.

100 FOR I = 1 to 10
110 FOR J = 1 to 10
120 ...
130 NEXT I
140 NEXT J

글 머리 기호 질문에 대답하려면 다음을 수행하십시오.

  • 예, 루프 변수가 FOR 범위 내에있는 경우
  • 그렇습니다. 내 지식으로는 그 경우입니다.

2
"BASIC 인터프리터는 그에 속하지 않는 FOR 루프에서 NEXT를 실행하지 않습니다"-이 문장이 틀린 구 BASIC 인터프리터 중 적어도 하나의 가족을 알고 있습니다.이를 "모든 고대 베이직 인터프리터"로 일반화 할 수는 없습니다.
Doc Brown

사양이 존재합니다. PDP-11 BASIC을 검색하십시오.
david.pfx

1
이 이상한 질문에 찔려 주셔서 감사합니다. 나는 책에서 사용 된 BASIC이 동일한 카운터 변수를 가진 두 번째 FOR 문을 만나면 첫 번째 FOR 문을 잊어 버리고 두 번째 FOR 문에서 루프를 다시 시작한다는 것을 확인했습니다. 이것은 어둠 속에서 당신의 찌르기와 모순됩니다. 루프를 작성하는 것은 이상한 방법이지만 BASIC은 어쨌든 냄새가납니다.
Wayne Conrad

2

"101 컴퓨터 게임"기본 기능

"101 Computer Games"의 마이크로 컴퓨터 판에 사용 된 BASIC의 방언은 FOR ... NEXT 루프의 본문을 적어도 한 번 실행합니다. 이것은 BASIC-80 v. 5 와 다릅니다 .

p.에서 "일반"기본에 대한 예외를 나열하는 i12 :

FOR ... TO ... STEP

루프 종료 테스트는 실행 후 h 후에 수행된다는 점을 제외하고 표준 BASIC에서와 같습니다. 즉,이 프로그램이 실행될 때 :

10 FOR X=2 TO 1
20 PRINT "HI"
30 NEXT X
40 END

"HI"가 인쇄됩니다 ...

이 때문에 BASIC의이 방언은 NEXT 문을 찾거나 여러 개의 FOR 문과 동일한 다음 명령문을 공유하는 데 아무런 문제가 없습니다. 정적 분석이 필요하지 않습니다. 모든 명령문이 발생하면 간단히 실행하면 어디에서나 NEXT 문으로 이동합니다.

BASIC-80이 비 순차적 NEXT를 처리 할 수 ​​있습니까?

대부분의 경우 BASIC-80 v.5가 허용하고 순서가 잘못된 NEXT 문을 허용하므로 FOR 문이 루프 본문을 건너 뛸 수 있습니다. 방법은 다음과 같습니다.

  • 인터프리터는 "실행 중"과 "다음으로 건너 뛰기"의 두 가지 상태를 얻습니다.
  • "실행 중"상태 인 경우, 인터프리터는 모든 명령문을 정상적으로 실행합니다.
  • FOR 문을 평가할 때 루프 본문을 건너 뛰면 상태가 "Nskiping to NEXT"로 변경됩니다.
  • "다음으로 건너 뛰기"상태 인 경우 인터프리터는 NEXT 및 무조건 GOTO를 제외한 모든 명령문을 건너 뜁니다 .
    • 무조건 GOTO 문이 뒤 따릅니다.
    • 변수가 FOR 문의 변수와 일치하거나 변수가 지정되지 않은 경우 NEXT 문은 "실행 중"상태로 다시 전환됩니다. 변수가 일치하지 않으면 인터프리터는 "다음으로 건너 뛰기"상태로 유지됩니다.

이것은 문제와 같은 간단한 병리학 적 순서를 처리합니다. IF ... GOTO 문 또는 GOSUB로 NEXT에 도달 한 경우는 처리하지 않습니다. 그렇게하는 코드는 질문에 이미 잘못된 코드보다 훨씬 나쁘므로 통역사가 그러한 경우를 지원하지 않는다고 간단하게 선언하는 것은 부당하지 않습니다. 통역사가 그러한 코드를 불에 태울 수도 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.