몽키 언어에 기능 추가!

12201 단어 Go
언어가 뭐예요?그렇게 생각하는 사람도 있겠지.몽키 언어는 일반적으로 사용하는 언어가 아니라 Go 언어로 작성된 해석기라는 책에서 쓴 독특한 언어다.
이 책에서는 Go 언어의 표준 라이브러리만 사용하여 설명 프로그램 언어를 만들 수 있습니다.
글자 분석기의 제작부터 최종 실현형(수치, 문자열, 진위값, 배열 etc), 사칙 연산, 변수 정의, 함수 정의 등 각종 문법.그 밖에 독립적으로 하나하나를 실현하기 위해 매번 실현할 때마다 실제적으로 조작할 수 있다!
제작된 기능은 육안으로 볼 수 있는 형태로 이동해 이해하기 쉽다.
가장 중요한 것은 자신이 처음부터 프로그래밍 언어를 작성하는 것이 매우 재미있고 재미있다는 것이다!

무순환 처리!


하지만!몽키 언어에서 프로그래밍 언어라고 할 수 있는 순환 처리의 실현은 없다!
그럼 추가 설치만 가능합니다!그래서 while 문장의 기능을 스스로 실현하려고 한다.
목표의 형식은 다음과 같이 집행할 수 있다.
>> let i = 0;
>> while (i < 5) {
..     puts("Hello");
..     let i = i + 1;
.. }
Hello
Hello
Hello
Hello
Hello
>> 
만들어주세요!

while 문장을 알아봅시다.


우선 무엇을 해야 합니까?
그래.while문을 썼는지 알아야지.지금 이러면'while'은 변수로 오인될 거야...
따라서 자구를 해석하기 위해'while'의 키워드에 접속하세요.
token.go
var keywords = map[string]TokenType{
    "fn":     Function,
    "let":    Let,
    "true":   True,
    "false":  False,
    "if":     If,
    "while":  While, // ここに追加
    "else":   Else,
    "return": Return,
}
상술한 키워드는 문장 해석 시 최초로 확인된 키워드들을 등록했다.여기에 등록된 것은 변수가 아니라 처음부터 의미 있는 문구로 식별되었다.한눈에 let 문장과if 문장 등을 등록한 것을 알 수 있다.
따라서 여기서'while'에 로그인하면'while'은 변수가 아니라while문의 시작을 의미하는 특별한 키워드라는 것을 알 수 있습니다.

while 문장의 AST 노드 등록


단지 문자 해석을 통해while 문장을 식별할 뿐, 당연히 아무 일도 일어나지 않을 것이다.왜냐하면 나는 아직 while 문장의 문법을 정의하지 않았기 때문이다.현재의 해석 프로그램을 보면 "while 문장의 시작을 찾았습니다. 어떻게 처리해야 하나요...?"의 상태.따라서while문에 쓴 내용을 해석해야 한다.
그러니까 해석해 봐요!내가 말하고 싶은 부분은 우선 해석된 결과를 저장하는 구조체(AST의 노드: 추상적인 문법 트리의 노드)를 정의하자.
정의는 좋지만 유지해야 할 정보는 무엇일까?
예를 들어 아주 간단한 while 문장을 봅시다.(무한순환은 신경 쓰지 마세요...)
while (i < 5) {
    let msg = "Hello";
    puts(msg);
}
이럴 때 뭘 유지해야 하지?
결론적으로 조건부와 집행부 두 개가 필요하다.
  • 조건부: i<5
  • 집행부:let msg="Hello"; puts(msg);
  • 이 두 가지를 유지하지 않으면 실제로 실행할 때 순환할 수 있습니까?무엇을 실행해야 합니까?모르겠어.
    따라서 이 정보를 저장하는 구조체를 정의합니다.
    type WhileExpression struct {
        Token       token.Token
        Condition   Expression
        Consequence *BlockStatement
    }
    
    이 구조체는 분석된 정보를 다음과 같이 저장한다.
  • Token:'while'을 나타내는 영패
  • Condition: i<5의 표현식
  • Consequence: "{}"의 모든 표현식의 형식을 나타냅니다 (let 문장이나puts 문장 부분).
  • 이렇게 유지함으로써 실제 집행할 때 조건부와 집행부의 정보를 끌어내어 집행할 수 있다.(Token 필드는 자신이 어떤 영패인지 식별하는 데 사용됩니다.)

    while 문장의 문법을 분석하다


    문법 해석 후의 정보의 보존지를 정의했기 때문에 이번에while문의 문법 해석을 진행하겠습니다.문법 분석기에while 문장을 추가로 분석하는 기능을 추가하세요.
    분석은 구체적으로 어떻게 진행해야 합니까?뭘 해석해야 되지?
    나는 이곳이 아마도 가장 어려운 부분일 것이라고 생각한다.하지만 걱정하지 마세요. 어렵기도 하지만 간단해요.몽키 언어가 아주 간단하게 설계되었기 때문이다.
    알겠습니다. while 문장의 문법 분석 절차를 고려해 보겠습니다.전제로 가설은'while'키워드를 발견했다."while"뒤에 뭐가 있을 거예요. 무슨 글자가 오면 끝나는 거예요?
    아까의 예로 생각해 봅시다.
    while (i < 5) {
        let msg = "Hello";
        puts(msg);
    }
    
    예를 보면 알 수 있듯이 공백과 줄 바꾸기를 제외하면 다음과 같은 형식이다.
    조건부 {집행부}
    그중에서 해석하고 싶은 것은 조건부와 집행부뿐이고 다음 절차라면 해석할 수 있지 않습니까?
  • "while"의 다음 문자가 "("이 아니라면 문법 오류
  • 분석 조건부의 공식
  • 조건부의 다음은''이며, 다음이'{'가 아니라면 문법 오류
  • 집행 단원의 표현식 분석
  • 실제로 이것만으로도 분석을 끝냈다.말로는 쉬운데.이거 코드로 보내볼게요.
    따라서 다음과 같은 문법 분석기로 "while"을 발견할 때 함수로 while 문장의 문법을 해석한다.
    func (p *Parser) parseWhileExpression() ast.Expression {
        // while のASTノードを生成
        expression := &ast.WhileExpression{Token: p.curToken}
    
        // 「while」の次が「(」で始まっていない場合、構文エラーなので処理終了
        if !p.expectPeek(token.LParen) {
            return nil
        }
    
        p.nextToken()
        // 条件部にある式の解析を行って格納
        expression.Condition = p.parseExpression(Lowest)
    
        // 条件式の次が「)」で終わっていない場合、構文エラーなので処理終了
        if !p.expectPeek(token.RParen) {
            return nil
        }
        // 条件部の次が「{」で始まっていない場合、構文エラーなので処理終了
        if !p.expectPeek(token.LBrace) {
            return nil
        }
    
        // 実行部の式すべてを解析し、格納
        expression.Consequence = p.parseBlockStatemnt()
    
        return expression
    }
    
    조건은 좀 다르지만 방금 처리 절차의 문법 오류 검사를 순서대로 진행할 뿐이다.이것만으로while 문장의 해석은 끝난다.아주 간단하게 해석해 냈어요!

    실행 while 문장


    마지막으로 지금까지 해석한 while 문장의 함수를 추가로 실행하세요.
    예전과 마찬가지로 처리 절차에서 고려해 보자.while 문장은 조건부의 식의 결과가 진짜인 상황에서 집행부의 식들입니다.1개 순환마다 조건부를 재평가하는 방식도 잊어서는 안 된다.그렇지 않으면 무한 순환이 생길 것이다.
    다시 말하면, 아래의 절차에 따라 처리하면 되지 않습니까?
  • 실행 조건 표현식 및 결과 획득
  • 조건식 결과가 사실이라면 다음과 같이 계속 실행한다
  • 집행부 내용
  • 조건 표현식 재실행 및 재평가 결과
  • 간단하네.그럼 설치해 보세요.다음은 지금까지 해석된 while 문장을 실제로 실행하는 함수입니다.
    func evalWhileExpression(we *ast.WhileExpression, env *object.Environment) object.Object {
        // 条件式の実行
        condition := Eval(we.Condition, env)
        if isError(condition) {
            return condition
        }
    
        var res object.Object
        res = Null
        for isTruthry(condition) {
            // 条件式が真の間、実行部の式を実行する
            res = Eval(we.Consequence, env)
            // 条件式の結果を更新する
            condition = Eval(we.Condition, env)
        }
        return res
    }
    
    이렇게 끝났어.방금 생각한 절차대로 실행했을 뿐, 특별히 쓸 만한 곳이 없으니, 정말 간단한 함수군요.

    순환 처리를 받았습니다!


    이상의 함수를 추가하는 등 이번에는 생략했지만 함수들을 부르는 데 몇 줄을 추가하면 완성된다.맑음, 몽키 언어로 순환 처리하면 쓸 수 있어!

    while 문장을 추가할 때 변경한 모든 것을 알고 싶은 사람은 아래의 제출을 보십시오.
    정말 이렇게 많이 추가해서 이렇게 간단하게 문법 하나를 실현했다.
    영패, 문자분석기, 문법분석기, 평가처리 등 인터페이스를 잘 활용해 적당한 추상화를 한 덕분이다.서로의 문법 정의에 영향을 주지 않기 위해 영향 범위를 명확하게 구분한다.
    이렇게 교묘하게 추상화되면 일종의 감동을 느낄 수 있다.똑같아요. "대단해!"이렇게 생각하는 사람 있어요?자신은 문재가 없기 때문에 전혀 전달되지 않았을 수도 있다...
    그렇든 아니든 모네키 언어 코드의 전모를 실제로 보셨으면 좋겠습니다.정말 대단합니다. 낭비를 최대한 줄이고 간단하게 이해하도록 설계되었습니다. 조금만 읽어도 아름다움을 알 수 있습니다.
    아래 링크는 자신이 경서를 쓰면서 만든 몽키 언어의 자료 라이브러리입니다. 실제로 보시기 바랍니다.while 문장 외에 원본 파일 실행 기능과 여러 줄 입력 기능 등이 추가되었습니다.나는 이것을 복제해서 끊임없이 만지작거리는 것도 괜찮다고 생각한다.
    Moneky 언어에는 다양한 기능이 추가됩니다.for 문장을 추가하든지, 내장 함수를 추가하든지.물론 브레이크 문구도 없으니 설치할 수 있으면 더 편하겠죠.

    마지막


    프로그래밍 언어를 직접 만들어 본 적이 없는 사람은 꼭 한번 만들어 보세요.이번에 소개된'Go언어로 만든 해석기'를 읽어서 실시하는 것도 좋고, 원본 코드를 읽어서 완전 자제에 도전하는 것도 좋다.
    처음에는 어렵다고 생각할 수도 있지만 막상 만들어보니 의외로 간단하다.또 추상화의 중요성을 실감할 수 있다고 본다.
    그리고 프로그래밍 언어를 만들어 자신의 언어 활동의 즐거움을 체험해 보세요.

    좋은 웹페이지 즐겨찾기