Skip to content

Instantly share code, notes, and snippets.

@ritalin
Last active December 14, 2015 23:48
Show Gist options
  • Save ritalin/5167881 to your computer and use it in GitHub Desktop.
Save ritalin/5167881 to your computer and use it in GitHub Desktop.
HaxeのType Macroによる、式木展開のサンプル

プロパティの参照

この式が

function(x) { 
  return x.y; 
}

こんな式木に

{ 
	expr => EFunction(
		null,
		{ 
			args => [
				{ name => x, type => null, opt => false, value => null }
			], 
			expr => { 
				expr => EBlock([
					{ 
						expr => EReturn(
							{ 
								expr => EField(
									{ 
										expr => EConst(CIdent(x)), 
										pos => #pos(./umock/TestReturns.hx:114: characters 48-49) 
									},
									y
								), 
								pos => #pos(./umock/TestReturns.hx:114: characters 48-51) 
							}
						), pos=> #pos(./umock/TestReturns.hx:114: characters 41-51) 
					}
				]), 
				pos => #pos(./umock/TestReturns.hx:114: characters 39-54) 
			}, 
			params => [], 
			ret => null 
		}
	), 
	pos => #pos(./umock/TestReturns.hx:114: characters 27-54) 
}

プロパティの値を変更

以下の式が

function(x) { 
  x.y = 250; 
}

こんな式木に

{ 
	expr => EFunction(
		null,
		{ 
			args => [
				{ name => x, type => null, opt => false, value => null }
			], 
			expr => { 
				expr => EBlock([
					{ 
						expr => EBinop(
							OpAssign,
							{ 
								expr => EField(
									{ 
										expr => EConst(CIdent(x)), 
										pos => #pos(./umock/TestReturns.hx:114: characters 41-42) 
									},
									y
								), 
								pos => #pos(./umock/TestReturns.hx:114: characters 41-44)
							},
							{ 
								expr => EConst(CInt(250)), 
								pos => #pos(./umock/TestReturns.hx:114: characters 47-50) 
							}
						), 
						pos => #pos(./umock/TestReturns.hx:114: characters 41-50) 
					}
				]), 
				pos => #pos(./umock/TestReturns.hx:114: characters 39-53) 
			}, 
			params => [], 
			ret => null 
		}
	), 
	pos => #pos(./umock/TestReturns.hx:114: characters 27-53) 
}

関数の実行(引数なし)

以下の式が

function(x) {
  return x.length();
}

こんな式木に

{ 
	expr => EFunction(
		null,
		{ 
			args => [
				{ name => x, type => null, opt => false, value => null }
			], 
			expr => { 
				expr => EBlock([
					{ 
						expr => ECall(
							{
								expr => EField(
									{								 
										expr => EConst(CIdent(x)), 
										pos => #pos(./umock/TestReturns.hx:114: characters 41-42) 
									},
									length
								), 
								pos => #pos(./umock/TestReturns.hx:114: characters 41-49) 
							},
							[]
						), 
						pos => #pos(./umock/TestReturns.hx:114: characters 41-51) 
					}
				]), 
				pos => #pos(./umock/TestReturns.hx:114: characters 39-54) 
			}, 
			params => [], 
			ret => null 
		}
	), 
	pos => #pos(./umock/TestReturns.hx:114: characters 27-54) 
}

関数の実行(引数あり)

以下の式が

function(x) { 
  return x.gimme("Hello", 123); 
}

こんな式木に

{ 
	expr => EFunction(
		null,
		{ 
			args => [
				{ name => x, type => null, opt => false, value => null }
			], 
			expr => { 
				expr => EBlock([
					{ 
						expr => EReturn(
							{ 
								expr => ECall(
									{ 
										expr => EField(
											{ 
												expr => EConst(CIdent(x)), 
												pos => #pos(./umock/TestParams.hx:33: characters 48-49) 
											},
											gimme
										), 
										pos => #pos(./umock/TestParams.hx:33: characters 48-55) 
									},
									[
										{ 
											expr => EConst(CString(Hello)), 
											pos => #pos(./umock/TestParams.hx:33: characters 56-63) 
										},
										{ 
											expr => EConst(CInt(123)), 
											pos => #pos(./umock/TestParams.hx:33:characters 65-68) 
										}
									]
								), 
								pos => #pos(./umock/TestParams.hx:33: characters 48-69) 
							}
						), 
						pos => #pos(./umock/TestParams.hx:33: characters 41-69) 
					}
				]), 
				pos => #pos(./umock/TestParams.hx:33: characters 39-72) 
			}, 
			params => [], 
			ret => null 
		}
	), 
	pos => #pos(./umock/TestParams.hx:33: characters 27-72) 
}

関数の実行(戻り値なし)

以下の式が

function(x) { 
  x.setDate(Date.now()); 
}

こんな式木に

{ 
	expr => EFunction(
		null,{ 
			args => [
				{ name => x, type => null, opt => false, value => null }
			], 
			expr => { 
				expr => EBlock([
					{ 
						expr => ECall(
							{ 
								expr => EField(
									{ 
										expr => EConst(CIdent(x)), 
										pos => #pos(./umock/TestReturns.hx:114: characters 41-42) 
									},
									setDate
								), 
								pos => #pos(./umock/TestReturns.hx:114: characters 41-50) 
							},
							[
								{ 
									expr => ECall(
										{ 
											expr => EField(
												{ 
													expr => EConst(CIdent(Date)), 
													pos => #pos(./umock/TestReturns.hx:114: characters 51-55) 
												},
												now
											), 
											pos => #pos(./umock/TestReturns.hx:114:characters 51-59) 
										},
										[]
									), 
									pos => #pos(./umock/TestReturns.hx:114: characters 51-61) 
								}
							]
						), 
						pos => #pos(./umock/TestReturns.hx:114: characters 41-62) 
					}
				]), 
				pos => #pos(./umock/TestReturns.hx:114: characters 39-65) 
			}, 
			params => [], 
			ret => null 
		}
	), 
	pos => #pos(./umock/TestReturns.hx:114: characters 27-65) 
}

クロージャ

以下の式が

var d = Date.fromString('2013-4-1');
var f = function(x) { 
  x.setDate(d); 
}

こんな式木に

{ 
	expr => EFunction(
		null,
		{ 
			args => [
				{ name => x, type => null, opt => false, value => null }
			], 
			expr => { 
				expr => EBlock([
					{ 
						expr => ECall(
							{ 
								expr => EField(
									{ 
										expr => EConst(CIdent(x)), 
										pos => #pos(./umock/TestReturns.hx:115: characters 41-42) 
									},
									setDate
								), 
								pos => #pos(./umock/TestReturns.hx:115: characters 41-50) 
							},
							[
								{
									expr => EConst(CIdent(d)), 
									pos => #pos(./umock/TestReturns.hx:115: characters 51-52) 
								}
							]
						), 
						pos => #pos(./umock/TestReturns.hx:115: characters 41-53) 
					}
				]), 
				pos => #pos(./umock/TestReturns.hx:115: characters 39-56) 
			}, 
			params => [], 
			ret => null 
		}
	), 
	pos => #pos(./umock/TestReturns.hx:115: characters 27-56) 
}

通常の関数コールと同じだけど、これでうまくいくのか・・・?

関数の実行(引数なし)その2

以下の呼び出しが

x.length();

こんな式木に

{ 
  expr => ECall(
		{ 
			expr => EField(
				{ 
					expr => EConst(CIdent(x)), 
					pos => #pos(./umock/TestReturns.hx:119: characters 25-26) 
				},
				length
			), 
			pos => #pos(./umock/TestReturns.hx:119: characters 25-33) 
		},
		[]
	), 
	pos => #pos(./umock/TestReturns.hx:119: characters 25-35) 
}

関数の実行(引数なし)その3

以下の呼び出しが

length();

こんな式木に


{ 
  expr => ECall(
		{ 
			expr => EConst(CIdent(length)), 
			pos => #pos(./umock/TestReturns.hx:119: characters 25-31) 
		},
		[]
	), 
	pos => #pos(./umock/TestReturns.hx:119: characters 25-33) 
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment