💭

スクリプト言語組み込み(umka編)

2025/01/20に公開

リハビリを兼ねてちょっと書いてみる。

概要

  • スクリプト組み込みの最低限必要なコードを書く
  • 言語を動かすときの特徴を書く

umkaってなに

https://github.com/vtereshkov/umka-lang

準備するもの(umka関連)

umka_api.h
libumka.a(ビルド時にリンクする)
libumka.dll(実行時にexeと同フォルダに置く)

コード

// Umka組み込みスクリプトのサンプル(3dcamサンプルを改造した)

#include <stdio.h>
#include "umka_api.h"

int x = 0;
int y = 0;

// Umkaの追加組み込み関数
void rlPlus(UmkaStackSlot* params, UmkaStackSlot* result)
{
    int* test = (int*)umkaGetParam(params, 0);
    x = x+1;
}

int main(void)
{
    // Umka初期化
    UmkaFuncContext umkaMyInit = { 0 }, umkaMyLoop = { 0 };
    void* umka = umkaAlloc();
    bool umkaOk = umkaInit(umka, "loop.um", NULL, 1024 * 1024, NULL, 0, NULL, false, false, NULL);

    if (umkaOk)
    {
        umkaAddFunc(umka, "MyPlus", &rlPlus);

        umkaAddModule(umka, "rl.um",
            "fn MyPlus*(dat: int)\n"
        );

        umkaOk = umkaCompile(umka);
    }

    if (umkaOk)
    {
        //正常コンパイル時の出力
        printf("Umka initialized\n");

        //関数登録(umka上で呼び出す関数)
        umkaGetFunc(umka, NULL, "MyInit", &umkaMyInit);
        umkaGetFunc(umka, NULL, "MyLoop", &umkaMyLoop);
    }
    else
    {
        //エラー時の出力
        UmkaError* error = umkaGetError(umka);
        printf("Umka error %s (%d, %d): %s\n", error->fileName, error->line, error->pos, error->msg);
    }

    if (umkaOk)
        umkaOk = umkaCall(umka, &umkaMyInit) == 0;

    if (!umkaOk)
    {
        UmkaError* error = umkaGetError(umka);
        printf("Umka runtime error %s (%d): %s\n", error->fileName, error->line, error->msg);
    }

    int exitCode = 0;

    // Main game loop
    if (umkaOk)
    {
        while (1)            // Detect window close button or ESC key
        {
            //umkaのソースコード内の関数をコールしてる。
            //Luaみたいな使い方ができる
            exitCode = umkaCall(umka, &umkaMyLoop);

            printf("%d, %d\n", x, y);

            if (!umkaAlive(umka))
            {
                if (exitCode != 0)
                {
                    UmkaError* error = umkaGetError(umka);
                    printf("Umka runtime error %s (%d): %s\n", error->fileName, error->line, error->msg);
                }
                break;
            }
        }
    }

    // Umka解放処理
    umkaFree(umka);

    return exitCode;
}

umkaのソースコード

import ( 
    "std.um"
    "rl.um"
)

const maxColumns = 20
var test: int

fn rnd(min, max: real): real {return min + (max - min) * std::frand()}

fn MyInit() {    
    test:=0
    rl::MyPlus(test)
}

fn MyLoop() {
    printf("Hello Umka!\n")
    test:=test+1
    rl::MyPlus(test)
}

実行時の特徴

  • 一度VMを動かしたとき、計算結果は保存されない。よって結果を保存する場合組み込み関数を作ってホストプログラム側に保存する必要がある。
  • 呼び出しは別途コードを書く必要ある。下記の記載が詳しい。
  • https://github.com/vtereshkov/umka-lang

なんで書いたの

準備に時間かからない簡単なサンプルが存在しないので、お試しで組み込めるコードを書いてみた。
あとゲーム開発再開するのに別分野でリハビリしてみた。

Discussion