오레올레 언어를 만드는 중

동기


  • JS로 원소의 WebGL을 만나 게임을 만들려고 했다.
  • GLSL에서 정적 타입 언어의 장점을 재인식한다.
  • JS로부터 WebGL을 괴롭히면, 형 변환의 오버헤드가 조금 신경이 쓰인다.
  • JS에서 벡터와 행렬의 연산 처리를 작성하는 것은 귀찮습니다. 그러나 GLSL의 벡터와 행렬의 연산 기능은 잘 되어 있고, JS도 이런 느낌으로 벡터 연산을 쓰면 편한데라고 생각한다.
  • WebAssembly가 되어 메이저 브라우저로 사용할 수 있게 된다. 이것은 뭐 LLVM의 Web판이라고도 할 수 있는 사양. 즉 언어를 만들 수 있다!
  • 알아보면 이미 emscripten 가 지원, AssemblyScript 가 되어 있었다!
  • 이것 사용하면 좋을까라고 생각하지만, emscripten은 지원 코드가 크다. 게다가 AssemblyScript 도 시도했지만, 조금 나의 요구에는 맞지 않을 것 같다.
  • 그리고 글쎄 GLSL 틱인 벡터·행렬 연산 기능을 가지는 C풍의 언어를 만들기로 했다.

  • 무엇으로 만드는가?


  • node.js 와 pratt parser 의 코드를 베이스로 구현하고 있다.
  • wasm 출력은 binaryen.js (emscripten에서 wasm으로 컴파일하여)을 사용하고 있습니다.
  • 우선 무엇인가의 컴파일은 웹 페이지상에서 할 수 있게 되어 있다.
  • 검증용 웹페이지



  • 리포지토리



    사양 개요(현시점에서 생각하는 것)


  • 정적 유형 지정
  • 자유 문맥 형식
  • C풍과 wasm을 강하게 의식한 구문
  • 그대로 wasm으로 컴파일되어 불필요한 지원 코드를 최대한 토하지 않는다

  • 사용자 정의형(사용자 정의형)이 정의·사용 가능
  • class 등은 갖지 않을지도 모른다

  • 가비지 수집하지 않음
  • wasm의 선형 메모리에 파괴적으로 액세스 가능
  • 힙/프리 스토어와 같은 메모리 관리 기구는 가지지 않는다. 다만 라이브러리로 쓸 수 있는 레벨의 구문은 준비한다.

  • 벡터 및 행렬 연산 기능이 GLSL처럼 내장되어 있습니다
  • 코루틴을 언어 기능으로

  • 사양 상세(정리 중)



    진행 상황


  • 2018년 3월 무렵부터 구현하기 시작했지만, 아직도 중반이라고 하는 느낌. .

  • 구현 상태 보고


  • 아직 구현 중
  • 구현 상황은 Twitter에서 중얼거리고 Togetter에서 요약합니다.


    컴파일 샘플


  • 아직 이 정도밖에 컴파일할 수 없습니다. .

  • 그 1



    출처


    // 関数 日本語使用可能
    i32 𩸽(i32 a,i32 b){
        return a * b;
    };
    
    // メイン 
    export i32 main(){
      i32 b = 0;
    
      for(i32 c = 0;c < 4;++c) {
        b = b + 1;
      }
      return 𩸽(b,b);// 4
    };
    
    

    움직이는 샘플



    움직이는 샘플

    컴파일 결과


    (module
     (type $𩸽 (func (param i32 i32) (result i32)))
     (type $main (func (result i32)))
     (memory $0 1 1)
     (export "main" (func $main))
     (func $𩸽 (; 0 ;) (type $𩸽) (param $0 i32) (param $1 i32) (result i32)
      (return
       (i32.mul
        (get_local $0)
        (get_local $1)
       )
      )
     )
     (func $main (; 1 ;) (type $main) (result i32)
      (local $0 i32)
      (local $1 i32)
      (set_local $0
       (i32.const 0)
      )
      (block
       (block $for0
        (set_local $1
         (i32.const 0)
        )
        (loop $loop1
         (br_if $for0
          (i32.eqz
           (i32.lt_s
            (get_local $1)
            (i32.const 4)
           )
          )
         )
         (block
          (set_local $0
           (i32.add
            (get_local $0)
            (i32.const 1)
           )
          )
         )
         (set_local $1
          (i32.add
           (get_local $1)
           (i32.const 1)
          )
         )
         (br $loop1)
        )
       )
      )
      (return
       (call $𩸽
        (get_local $0)
        (get_local $0)
       )
      )
     )
    )
    

    그 2:유저 정의형(커스텀형)



    출처


      type Bar {
      public:
        i32 barA = 3;
        i32 barB = 4;
      };
    
      type Foo {
      public:
        i32 a = 1;
        i32 b = 2;
        Bar c;
      };
    
      export i32 main(){
        Foo foo,foo1;
        foo.a = 2;
        foo1 = foo;  
        foo.a = 10;
        return foo.a * foo1.a;
      };
    

    움직이는 샘플(컴파일 결과)



    움직이는 샘플(컴파일 결과)

    그 3:포인터



    소스 코드


    export i32 main(){
      i32 p = 0;// メモリオフセット0をポインタにセット
      *p = 32.0f;// floatの値を保存
      u32 a = *p;// float値をu32値として取り出し
      return a;
    };
    

    움직이는 샘플(컴파일 결과)



    움직이는 샘플(컴파일 결과)

    그 4:형 별칭



    소스 코드


    export i32 main(){
      // type エイリアス
      type& T = i32;        
      type& T1 = T;
    
      T a = 1; 
      T1& b = a; 
      ++a;
      b += 2;
      return a;// 4
    };
    

    움직이는 샘플(컴파일 결과)



    움직이는 샘플(컴파일 결과)

    그 5:const 변수



    소스 코드


    const WIDTH = 320;
    const HEIGHT = 240;
    
    export i32 main(){
      i32 a = WIDTH * HEIGHT;
      return a;// 76800
    };
    
    

    움직이는 샘플(컴파일 결과)



    움직이는 샘플(컴파일 결과)

    그 6:reinterpret cast



    소스 코드


    export f64 main(){
      i64 a = 0x3fc4 0000 0000 0000xl;// f64を整数値として代入
      f64 b = (^f64)a;// reinterpret cast
    
      return b;// 0.15625
    };
    
    

    움직이는 샘플(컴파일 결과)



    움직이는 샘플(컴파일 결과)

    그 7:캐스트



    소스 코드


    // キャストの実装(ネイティブ型同士のみ)
    export i32 main(){
      i32 b = 10;
      f64 c = (f64)b + 10.0lf;
      return (i32)c;
    };
    
    
    

    움직이는 샘플(컴파일 결과)



    움직이는 샘플(컴파일 결과)

    그 8:수치 리터럴



    소스 코드


    export i32 main(){
      i32 a = 0x1 00x;// 16進リテラル(スペースで値が区切れる)
      ,b = 0b1 0000 0000 b;// 2進数リテラル
      if( a == b){
        return 1;
      } 
    
      return 0;
    };
    
    
    
    

    움직이는 샘플(컴파일 결과)



    움직이는 샘플(컴파일 결과)

    좋은 웹페이지 즐겨찾기