/*
 *	jtdotassign.c
 *
 *	JoyToyインタプリタ
 *
 *	* Sun Jan 01 00:00:00 JST 2006 Naoyuki Sawa
 *	- 作成開始。
 *	* Tue Jan 31 00:00:00 JST 2006 Naoyuki Sawa
 *	- 1st リリース。
 *	* Sat Jun 17 05:26:02 JST 2006 Naoyuki Sawa
 *	- FIELD_OFFSET()→offsetof()に変更。
 */
#include "app.h"

/*****************************************************************************
 *	JTDOTASSIGN
 *****************************************************************************/

typedef struct _JTDOTASSIGN {
	int refcnt;
	JTCODE_INTERFACE* jtcode_interface;
	//
	JTCODE_INTERFACE** code;	/* オブジェクト */
	JTSYMBOL_INTERFACE** symbol;	/* フィールド変数名を表すシンボル */
	JTCODE_INTERFACE** value;	/* フィールド変数に設定する値 */
} JTDOTASSIGN;

IMPLEMENT_JTCODE_INTERFACE(JTDOTASSIGN, jtdotassign)

const INTERFACE_MAP jtdotassign_interface_map[] = {
	{ JTCODE_INTERFACE_ID, offsetof(JTDOTASSIGN, jtcode_interface), &jtcode_interface },
	{ 0/*終端*/ },
};

JTCODE_INTERFACE**
jtdotassign_create(JTCODE_INTERFACE** code, JTSYMBOL_INTERFACE** symbol, JTCODE_INTERFACE** value)
{
	JTDOTASSIGN* this = calloc(1, sizeof(JTDOTASSIGN));
	if(!this) {
		DIE(); /* メモリ不足 */
	}
	this->refcnt = 1;
	apply_interface_map(this, jtdotassign_interface_map);

	/* オブジェクト、フィールド変数名を表すシンボル、フィールド変数に設定する値を格納します。 */
	safe_assign(this->code, code);
	safe_assign(this->symbol, symbol);
	safe_assign(this->value, value);

	return &this->jtcode_interface;
}

static void
jtdotassign_delete(JTDOTASSIGN* this)
{
	/* オブジェクト、フィールド変数名を表すシンボル、フィールド変数に設定する値を解放します。 */
	safe_release(this->code);
	safe_release(this->symbol);
	safe_release(this->value);

	free(this);
}

/*****************************************************************************
 *	JTCODE_INTERFACE
 *****************************************************************************/

static JTCODE_INTERFACE**
jtcode_run(JTCODE_INTERFACE** intf)
{
	JTDOTASSIGN* this = CONTAINING_RECORD(intf, JTDOTASSIGN, jtcode_interface);
	//
	JTCODE_INTERFACE** code = NULL;
	JTOBJECT_INTERFACE** object = NULL;

	/* メソッドを呼び出す直前のタイミングで、オブジェクトを評価します。 */
	safe_attach(code, (*this->code)->run(this->code)); /* シンボルを解決して、オブジェクトを取得する処理など */
	safe_assign_interface(object, code, JTOBJECT_INTERFACE);
	if(!object) {
		DIE(); /* オブジェクトでない (読み込んだプログラムのエラー) */
	}

	/* フィールド変数に設定する値を評価します。 */
	safe_attach(code, (*this->value)->run(this->value));

	/* フィールド変数の値を設定します。 */
	(*object)->set_field_value(object, this->symbol, code);

	/* 不要になったインターフェイスを解放します。 */
	safe_release(object);

	return code;
}

