루비로 BASIC 인터프리터 만들기: Part 1

BASIC interpreter in Ruby from scratch part 1

작성자
발행일
2025년 08월 14일

핵심 요약

  • 1 본 문서는 루비(Ruby) 언어를 사용하여 BASIC 언어 인터프리터를 처음부터 구축하는 과정의 첫 번째 부분을 상세히 설명합니다.
  • 2 Lexer, Parser, REPL, 변수 관리, 수식 파싱, 그리고 GOTO 및 IF-ELSE와 같은 기본적인 제어 흐름 구현을 다룹니다.
  • 3 이 파트에서는 복잡한 산술, 논리 및 비트와이즈 연산을 처리할 수 있는 견고한 파싱 엔진의 구축을 목표로 합니다.

도입

이 문서는 프로그래밍 언어, 특히 BASIC 인터프리터를 루비로 직접 구현하는 여정의 첫 번째 단계입니다. 1975년 빌 게이츠와 폴 앨런이 개발한 Altair BASIC을 재현하는 데 중점을 두며, 이는 수백만 명이 프로그래밍을 시작하는 데 기여한 역사적으로 중요한 언어입니다. 본 파트에서는 인터프리터의 핵심 아키텍처와 기본적인 기능 구현에 대한 포괄적인 가이드를 제공합니다.

인터프리터는 Lexer, Parser, 그리고 실제 실행을 담당하는 Interpreter라는 세 가지 주요 구성 요소로 이루어집니다. Lexer는 소스 코드를 토큰으로 분할하고, Parser는 이 토큰들을 문법 규칙에 따라 의미 있는 구조로 변환합니다. 본 구현에서는 먼저 사용자와 상호작용하는 REPL(Read-Eval-Print Loop)과 유사한 프로그램을 구축하여, QUIT, CLEAR, HELP, NEW, LIST와 같은 기본 명령어를 처리하고 프로그램 라인을 메모리에 저장하는 기능을 추가합니다.

Lexer는 숫자, 식별자, 연산자, 문자열 리터럴 등 BASIC의 네 가지 필수 토큰 유형을 처리하도록 구현됩니다. 특히, BASIC의 대소문자 구분 없는 특성을 고려하여 식별자는 대문자로만 인식하며, 변수 유형 접미사($ 등)를 지원합니다. 이어서 PRINT 문을 구현하여 문자열, 변수 값을 출력하고 쉼표(,)와 세미콜론(;)과 같은 구분자를 처리하여 출력 형식을 제어합니다.

변수 선언 및 사용을 위해 LET 문이 도입됩니다. 모든 변수는 전역 해시($variables)에 저장되며, 초기에는 간단한 숫자 값만 처리합니다. 이후에는 재귀 하향식 파싱(recursive descent parsing)을 통해 산술, 비트와이즈, 논리, 비교 연산을 포함한 복잡한 수식 평가 기능을 추가합니다. 이 파서는 연산자 우선순위(예: 곱셈이 덧셈보다 먼저)와 결합성(예: 지수 연산의 우측 결합성)을 정확히 따르며, NOT과 같은 단항 연산자도 지원합니다.

마지막으로, 프로그램의 제어 흐름을 관리하는 GOTOIF-THEN-ELSE 문을 구현합니다. GOTO는 특정 라인 번호로 무조건 점프하는 기능을 제공하며, IF 문은 조건식 평가 결과에 따라 코드 블록을 실행하거나 건너뛰는 기능을 수행합니다. 특히, 초기 BASIC 버전에는 없었던 ELSE 절을 추가하여 현대적인 조건부 실행을 가능하게 합니다. 이 모든 과정에서 eval_expr와 같은 헬퍼 함수를 사용하여 표현식 평가를 모듈화하고 재사용성을 높입니다.

결론

이 파트에서는 루비로 BASIC 인터프리터의 견고한 기반을 성공적으로 구축했습니다. REPL, Lexer, Parser의 핵심 구성 요소를 구현하고, `PRINT`, `LET` 문을 통해 변수 관리 및 복잡한 수식 처리를 가능하게 했습니다. 또한, `GOTO`와 `IF-THEN-ELSE` 문을 통해 기본적인 제어 흐름을 확립하여 다양한 유용한 프로그램을 실행할 수 있는 수준에 도달했습니다. 다음 파트에서는 루프, 배열, 주석, 함수, 서브루틴, 사용자 입력 처리와 같은 더욱 확장된 기능을 구현하여 인터프리터의 완성도를 높일 예정입니다.

댓글 0

댓글 작성

0/1000
정중하고 건설적인 댓글을 작성해 주세요.

아직 댓글이 없습니다

첫 번째 댓글을 작성해보세요!