시리즈:쉽게 배우는 프로그래밍 입문/FORTH

문서의 내용이 너무 쉬워서 오늘부터 프로그래밍 할 수 있을 것 같습니다.

이 문서에는 독자적으로 연구한 내용이 들어갑니다. 다른 사람의 의견을 존중하면서 무례하지 않도록 작성해 주시고, 의견 충돌 시 토론 문서에서 토론해 주세요.
리브레 프로그래밍 시리즈
초급
프로그래밍
중급
프로그래밍
고급
프로그래밍
Python
협업

안녕하세요. 이 문서는 FORTH(이하 포스)라는 스택 기반 언어에 대한 문서입니다. 이미 망한 언어! 죽어서 거의 쓰이지 않는다는 언어!!입니다만, 스택을 이용한 물건이라는 점에서 흥미를 돋우는 언어이기도 합니다. 포스가 처음 등장했을 당시, 사람들은 포스가 세상을 지배할 것이라고 생각했다지만…

망한 언어기 때문에 실생활에서 단순하게 사용할 정도(계산기?)로만 소개할게요. (사실 잘 모름ㅋㅋ)

※이 문서는 쉽게 배우는 시리즈 중 하나이지만 집단연구 문서는 아닙니다. 이 언어를 잘 알고 있다면 좀 뜯어고쳐 주세요. 와타시와 혼자쓰기 사비시데스네.

시작[편집 | 원본 편집]

오픈소스이자 현재 쉽게 구할 수 있는 포스 구현인 Gforth는 현재 홈페이지에서 스냅샷을 제공하고 있습니다. 여러 링크들이 보일텐데, 현재 날짜인 2016년 2월 21일, 윈도우 플랫폼 기준으로 다운받을 수 있는 32비트 버전과 64비트 버전이 있으니 본인에 맞춰 다운받으면 됩니다.

유급[편집 | 원본 편집]

포스는 후위 표기법을 사용하는 스택 기반 언어입니다. 이 간단한 소개 문장 하나에서 모르는 단어가 벌써 두개나 나왔네요. 하나씩 살펴봅시다.

표기법[편집 | 원본 편집]

후위 표기법은 수학 식을 표현하는데 쓰이는 세 가지 방법 중 하나입니다.

중위 표기법[편집 | 원본 편집]

중위 표기법은 우리가 일상적으로 사용하는 방법입니다.

2 * (3 + 4)

사람 입장에서는 왼쪽에서 오른쪽으로 훑어 나가며 편하게 식을 계산할 수 있지만, 컴퓨터 입장에서는 계산하기도 힘들고, 또 위 예문처럼 서로 우선순위가 다른 연산자를 처리하기 위해 괄호가 꼭 있어야 한다는 부작용이 있죠.

전위 표기법[편집 | 원본 편집]

전위 표기법은 주로 리스프 어족의 언어에서 사용되는 표기법입니다. 폴란드 표기법이라고도 하는데요, 이 표기법은 연산자를 피연산자 앞으로 옮겨서 식을 표기합니다.

  • 2 + 3 4

보다시피 괄호가 없어도 연산자의 우선순위를 올바르게 지정 할 수 있습니다. 다만 리스프 어족에서는 S-Expression이라는 방식을 써서 괄호를 쓰는 대신 연산자가 여러 개의 피연산자를 받을 수 있도록 했어요.

(* 2 (+ 3 4 5 6 7 8) 9 10 11)

후위 표기법[편집 | 원본 편집]

이제 드디어 포스에서 쓰이는 후위 표기법이 나왔습니다. 아까 전위 표기법을 폴란드 표기법이라고 했던거 기억나시죠? 후위 표기법은 그와 연관되어 역폴란드 표기법이라고도 합니다.

2 3 4 + *

보다시피 전위 표기법의 연산자 위치만 반대로 해주면 그게 후위 표기법이 됩니다. 포스의 모든 코드는 예외없이 후위 표기됩니다. 낯설기 때문에 익숙하지 않다면, 한국어를 그대로 옮긴다고 생각해도 무방합니다. 예를 들어 위 식은 한국어로 다음과 같이 표현되는데,

2와 (3과 4를 더한 것)을 곱한 것

한국어로 쓰면 약간 모호해서 괄호를 넣긴 했지만, 저 형태에 주목하세요. 중요한 부분을 강조해 보겠습니다.

2 3 4 더한 것 곱한 것
2 3 4 + *

둘을 비교해 보고 후위 표기법으로 식을 쓰는데 익숙해져 보세요.

스택[편집 | 원본 편집]

포스는 스택이라는 자료구조를 사용합니다. 말하자면 바구니 같은 거예요. 이 바구니는 물건을 넣는 족족 쌓여서, 가장 마지막에 넣은 물건이 첫 번째로 보이는 구조인 겁니다. 그리고 꺼내는 것도 마지막부터 역순으로 꺼내야 합니다.

  • 한 줄 요약: 스택(바구니)에 들어간 값은 마지막으로 입력한 것부터 꺼내진다.

단어[편집 | 원본 편집]

포스에서 사용하는 명령 혹은 함수입니다. 포스의 모든 계산은 단어를 통해서 이루어지며, 별다른 문법이 없습니다.

1 2 + .  \ 3

위 코드의 +.도 단어이며, 보이는 것처럼 공백으로 구분하지요.

값의 입력[편집 | 원본 편집]

변수? 리스트? 필요 없습니다! 포스는 저 것들을 쓰지 않고도 값을 보존하고 계산할 수 있어요. 변수 없이도…ㅠㅠ 다음처럼 값을 입력해 봅시다.

1 2

다음처럼 스택에 값이 들어간 것이 보이지요?

Stack<10> 1 2

만약 보이지 않는다면, .s 단어를 이용하여, 데이터 스택에 들어간 값들을 볼 수 있어요.

값의 출력[편집 | 원본 편집]

스택에 들어간 값을 출력하기 위해서는 .단어를 사용합니다.

1 2
    ok
Stack<10> 1 2
.
2    ok
Stack<10> 1

1과 2를 입력하고서 값을 출력하니, 화면에는 2가 찍히고 스택에는 1만 남았네요? 스택의 출력은 마지막부터 역순!

사칙연산[편집 | 원본 편집]

계산의 기본은 사칙연산이죠? 이를 위해 포스는 +·-·*·/의 단어를 제공하고 있어요.

0 1 +      \  1 = 0 + 1
2 3 4 + *  \ 14 = 2 * (3 + 4)
    ok
Stack<10> 1 14

오호~ 스택의 특성에 따라 거꾸로 계산되네요? 스택을 이용한 계산에는 값과 연산자가 순서대로 반응하는 것이라서, 괄호를 사용하지 않아요.

단어 작성 및 사용[편집 | 원본 편집]

단어는 포스의 연산자, 명령어 혹은 함수와 같은 개념입니다. 이제 여러분은 사칙연산 항목을 통해서 단순한 계산을 할 수 있게 되었습니다. 그럼 이제 총합을 구해봅시다.

1 2 3 4 5 6 7 8 9 10 + + + + + + + + +
    ok
Stack<10> 55

헥헥, 아니!! 연산자 쓰기가 넘 힘드네요ㅠㅠ 계산기에서 자주 쓰이는 기능 중 하나가 총합인데, 이렇게 힘들수가! 그러니 단어를 만들어 좀 편하게 계산해 봅시다.

: SUM  DEPTH 1 <> IF + RECURSE THEN ;
    ok
Stack<10>

이제 SUM이라는 단어를 만들었습니다. 구조를 살펴볼까요?

:       \ 단어를 정의하는 단어입니다.
SUM     \ 단어 이름.
DEPTH   \ 현재 스택의 깊이를 확인.
1 <> IF \ 판단문. 깊이가 1로 떨어질 때까지 동작시키려는 겁니다.
+       \ 총합이니까, 더해야겠지요?
RECURSE \ 재귀. 판단문과 연계하여 계속 SUM을 호출하도록.
THEN    \ 판단문 종료.
;       \ 단어 정의 마침.

그러니까, :으로 단어 만들기를 시작해서, SUM이라는 이름을 주고서, "스택의 깊이가 1이 될 때까지 반복해서 더해보자"고한 뒤에, ;으로 단어 만들기를 마치는 겁니다.

1 2 3 4 5 SUM
    ok
Stack<10> 55

오~ 잘 동작하네요. 룰루랄라♪ ㅋㅋㅋ

단어들[편집 | 원본 편집]

단어들이 궁금하다면, WORDS 단어를 사용해 보세요. 지금 작동하고 있는 어휘들을 쭉 보여줄 겁니다.

초급[편집 | 원본 편집]

설명문(주석)[편집 | 원본 편집]

설명문에는 역슬래시(\)와 소괄호((…))를 사용해요.

\ 설명문이다.
( 주석이다. )
Stack<10>

전자는 설명을 시작하면, 끝까지 설명문이고, 후자는 코드 사이에 삽입할 수가 있지요. 설명문은 포스에서 스택 이펙트라는 것을 표현하는데 종종 사용합니다.

스택 조작[편집 | 원본 편집]

포스에서는 스택 안의 값들을 이리저리 움직이며 조작하는 단어들을 제공해요. 어떤 일을할 때, 우선순위가 필요하거나 다른 계산을 먼저하고 싶을 때 사용하는 거죠. 기초적인 단어로 다음 네 가지를 뽑았어요.

  1. DUP ( x -- x x )
  2. DROP ( x -- )
  3. ROT ( a b c -- b c a )
  4. -ROT ( a b c -- c a b )

스택 조작이 연산에 도움이 되긴하지만, 너무 많이 혹은 너무 깊이 조작해서는 안됩니다. 자신의 정신도 함께 복제·삭제·회전될 가능성이 높아요. 주의합시다.

DUP:[편집 | 원본 편집]

스택의 처음 값(맨 위 값)을 복제 합니다.

2 DUP
    ok
Stack<10> 2 2

2를 복제하니까 2가 두 개가 되었어요.
2를 복제하니까 2가 두 개가 되었어요.

DROP:[편집 | 원본 편집]

스택의 처음 값을 삭제 합니다.

10    \ ⏎ 
DROP  \ ⏎ 
    ok
Stack<10>

ROT/-ROT:[편집 | 원본 편집]

스택의 값을 회전시킵니다. 스택의 처음 값 이하, 3개의 값을 회전시켜요. @_@

1 2 3 4 ROT
    ok
Stack<10> 1 3 4 2

1 2 3 4를 회전시켰더니, 1 3 4 2이 되었어요! ROT는 처음 값 이하, 3개의 값을 아래쪽으로 회전합니다. -ROT는 반대로 위쪽으로 회전.

판단문[편집 | 원본 편집]

포스에도 다른 언어들처럼 판단문이 가능하지요. 기본은 역시 if문. 다음 단어들을 제공합니다. IF, ELSE, THEN. 코드를 봐주세요.

10 5 >      \ 10이 5보다 크다면,
IF   -1     \ -1을 입력하고,
ELSE  0     \ 그렇지 않다면, 0을 입력.
THEN
    ok
Stack<10> -1

IF는 값을 비교하여, 0이면 거짓, 나머지는 참으로 판단합니다. IFTHEN과 짝을 이루며, ELSE는 해당하는 처리를 하고 싶지 않다면 없어도 좋아요. 참고로 포스 내에서 참값은 -1.

대소 비교:[편집 | 원본 편집]

대소 비교를 위해 다음 > < = >= <= <>과 같은 단어들을 사용해요. (BASIC의 비교 연산자와 같아요.) 덧붙여서 0=와 같이 0과 관계된 비교연산을 위한 편의 단어들도 제공합니다.

반복문[편집 | 원본 편집]

단순한 작업에는 필요없어요. 그냥 코드 복붙하세요.

DO….LOOP:[편집 | 원본 편집]

예문: 삼각형 그리기[편집 | 원본 편집]

초급 항목에서 익혔던 것들을 토대로 삼각형 그리기를 해봐요.

: >ODD    DUP 0 <> IF 2 * 1 - THEN ;    \ 판단문.
: .STAR   [CHAR] * EMIT ;               \ 별표(*) 출력인데, 넘어가요.
: .STARS  >ODD 0 ?DO .STAR LOOP ;       \ 반복문.
: TRIANGLE
    6 0 DO
        5 i - SPACES
        i .STARS CR
        LOOP
    ;
TRIANGLE                                \ 삼각형 그리기.

    *
   ***
  *****
 *******
*********
   ok
Stack<10>

중급[편집 | 원본 편집]