SymbolAstResult UnaryExpression::GenerateAst(shared_ptr<SymbolAstScope> scope, SymbolAstContext& context, shared_ptr<ast::AstDeclaration> state)
		{
			AstUnaryOperator astOp = AstUnaryOperator::Not;
			switch (op)
			{
			case UnaryOperator::Not:
				astOp = AstUnaryOperator::Not;
				break;
			case UnaryOperator::Positive:
				astOp = AstUnaryOperator::Positive;
				break;
			case UnaryOperator::Negative:
				astOp = AstUnaryOperator::Negative;
				break;
			}

			SymbolAstResult result;
			vector<AstExpression::Ptr> exprs;
			int exprStart = 0;

			result.MergeForExpression(operand->GenerateAst(scope, context, state), context, exprs, exprStart, state);

			auto ast = make_shared<AstUnaryExpression>();
			ast->op = astOp;
			ast->operand = exprs[0];
			return result.ReplaceValue(ast);
		}
		SymbolAstResult UnaryExpression::GenerateAst(shared_ptr<SymbolAstScope> scope, SymbolAstContext& context, shared_ptr<ast::AstDeclaration> state)
		{
			AstDeclaration::Ptr astOp;
			switch (op)
			{
			case UnaryOperator::Not:
				astOp = scope->opNot;
				break;
			case UnaryOperator::Positive:
				astOp = scope->opPos;
				break;
			case UnaryOperator::Negative:
				astOp = scope->opNeg;
				break;
			}

			SymbolAstResult result;
			vector<AstExpression::Ptr> exprs;
			int exprStart = 0;
			result.MergeForExpression(operand->GenerateAst(scope, context, state), context, exprs, exprStart, state);

			auto stat = make_shared<AstExpressionStatement>();

			auto invoke = make_shared<AstInvokeExpression>();
			stat->expression = invoke;
			{
				auto ref = make_shared<AstReferenceExpression>();
				ref->reference = astOp;
				invoke->function = ref;
			}
			{
				auto arg = make_shared<AstReferenceExpression>();
				arg->reference = state;
				invoke->arguments.push_back(arg);
			}
			invoke->arguments.push_back(exprs[0]);

			auto lambda = Expression::GenerateContinuationLambdaAst(scope, context, state);
			invoke->arguments.push_back(lambda);
			
			auto ast = make_shared<AstReferenceExpression>();
			ast->reference = lambda->arguments[1];

			result.AppendStatement(stat);
			return result.ReplaceValue(ast, lambda);
		}
		SymbolAstResult ListExpression::GenerateAst(shared_ptr<SymbolAstScope> scope, SymbolAstContext& context, shared_ptr<ast::AstDeclaration> state)
		{
			SymbolAstResult result;
			vector<AstExpression::Ptr> exprs;
			int exprStart = 0;

			for (auto element : elements)
			{
				result.MergeForExpression(element->GenerateAst(scope, context, state), context, exprs, exprStart, state);
			}

			auto ast = make_shared<AstNewArrayLiteralExpression>();
			for (auto expr : exprs)
			{
				ast->elements.push_back(expr);
			}
			return result.ReplaceValue(ast);
		}
示例#4
0
		void SymbolAstResult::MergeForStatement(const SymbolAstResult& result, AstDeclaration::Ptr& state)
		{
			AppendStatement(result.statement);
			if (result.RequireCps())
			{
				continuation = result.continuation;
			}

			if (continuation)
			{
				state = continuation->arguments[0];
			}
		}
示例#5
0
		void SymbolAstResult::MergeForExpression(const SymbolAstResult& result, SymbolAstContext& context, vector<AstExpression::Ptr>& exprs, int& exprStart, AstDeclaration::Ptr& state)
		{
			if (result.RequireCps())
			{
				auto block = make_shared<AstBlockStatement>();
				for (int i = exprStart; (size_t)i < exprs.size(); i++)
				{
					auto var = make_shared<AstDeclarationStatement>();
					{
						auto decl = make_shared<AstSymbolDeclaration>();
						decl->composedName = T("$var") + context.GetUniquePostfix();
						var->declaration = decl;

						auto declstat = make_shared<AstDeclarationStatement>();
						declstat->declaration = decl;
						block->statements.push_back(declstat);

						auto assign = make_shared<AstAssignmentStatement>();
						block->statements.push_back(assign);

						auto ref = make_shared<AstReferenceExpression>();
						ref->reference = decl;
						assign->target = ref;

						assign->value = exprs[i];
					}
					
					auto ref = make_shared<AstReferenceExpression>();
					ref->reference = var->declaration;
					exprs[i] = ref;
				}
				block->statements.push_back(result.statement);

				if (continuation)
				{
					continuation->statement = block;
				}
				else
				{
					statement = block;
				}
				continuation = result.continuation;
				exprStart = exprs.size();
				state = continuation->arguments[0];
			}
			exprs.push_back(result.value);
		}
示例#6
0
		ast::AstAssembly::Ptr GenerateAst(SymbolAssembly::Ptr symbolAssembly)
		{
			auto assembly = make_shared<AstAssembly>();
			auto scope = make_shared<SymbolAstScope>();

			multimap<SymbolFunction::Ptr, SymbolFunction::Ptr> multipleDispatchChildren;
			map<SymbolFunction::Ptr, SymbolModule::Ptr> functionModules;
			map<SymbolFunction::Ptr, AstFunctionDeclaration::Ptr> functionAsts;
			GenerateStaticAst(symbolAssembly, assembly, scope, multipleDispatchChildren, functionModules, functionAsts);
			GenerateMultipleDispatchAsts(symbolAssembly, assembly, scope, multipleDispatchChildren, functionModules, functionAsts);

			for (auto fap : functionAsts)
			{
				auto func = fap.first;
				auto ast = fap.second;
				auto module = functionModules.find(func)->second;

				SymbolAstContext context;
				context.function = ast;
				context.continuation = ast->continuationArgument;
				auto itdecl = ast->arguments.begin();
				if (func->cpsStateVariable)
				{
					context.createdVariables.push_back(func->cpsStateVariable);
					scope->readAsts.insert(make_pair(func->cpsStateVariable, ast->stateArgument));
				}
				itdecl++;
				if (func->categorySignalVariable)
				{
					context.createdVariables.push_back(func->categorySignalVariable);
					scope->readAsts.insert(make_pair(func->categorySignalVariable, ast->signalArgument));
					itdecl++;
				}
				if (func->cpsContinuationVariable)
				{
					context.createdVariables.push_back(func->cpsContinuationVariable);
					scope->readAsts.insert(make_pair(func->cpsContinuationVariable, ast->continuationArgument));
				}
				if (func->resultVariable)
				{
					context.createdVariables.push_back(func->resultVariable);
					scope->readAsts.insert(make_pair(func->resultVariable, ast->resultVariable));
				}

				for (auto arg : func->arguments)
				{
					if (auto var = dynamic_pointer_cast<VariableArgumentFragment>(arg.second))
					{
						if (var->type == FunctionArgumentType::Argument)
						{
							continue;
						}
						else if (var->type == FunctionArgumentType::Assignable)
						{
							context.createdVariables.push_back(arg.first);
							scope->readAsts.insert(make_pair(arg.first, *itdecl++));
							scope->writeAsts.insert(make_pair(arg.first, *itdecl++));
							continue;
						}
						else if (var->type == FunctionArgumentType::Expression)
						{
							context.createdVariables.push_back(arg.first);
							scope->readAsts.insert(make_pair(arg.first, *itdecl++));
							scope->writeAsts.insert(make_pair(arg.first, nullptr));
							continue;
						}
					}
					context.createdVariables.push_back(arg.first);
					scope->readAsts.insert(make_pair(arg.first, *itdecl++));

					if (auto func = dynamic_pointer_cast<FunctionArgumentFragment>(arg.second))
					{
						auto ast = dynamic_pointer_cast<AstFunctionDeclaration>(func->declaration->GenerateAst(module));
						scope->functionPrototypes.insert(make_pair(arg.first, ast));
					}
				}

				{
					AstDeclaration::Ptr state = ast->arguments[0];
					SymbolAstResult result = func->statement->GenerateBodyAst(scope, context, state, nullptr);
					result.MergeForStatement(Statement::GenerateExitAst(scope, context, state), state);
					ast->statement = result.statement;
				}
				{
					auto stat = make_shared<AstDeclarationStatement>();
					stat->declaration = ast->resultVariable;

					if (auto block = dynamic_pointer_cast<AstBlockStatement>(ast->statement))
					{
						block->statements.insert(block->statements.begin(), stat);
					}
					else
					{
						block = make_shared<AstBlockStatement>();
						block->statements.push_back(stat);
						block->statements.push_back(ast->statement);
						ast->statement = block;
					}
				}
				if (!dynamic_pointer_cast<AstBlockStatement>(ast->statement))
				{
					auto block = make_shared<AstBlockStatement>();
					block->statements.push_back(ast->statement);
					ast->statement = block;
				}

				for (auto var : context.createdVariables)
				{
					scope->readAsts.erase(var);
					scope->writeAsts.erase(var);
					scope->functionPrototypes.erase(var);
				}
			}

			assembly->RoughlyOptimize();
			assembly->SetParent();
			return assembly;
		}
		SymbolAstResult BinaryExpression::GenerateAst(shared_ptr<SymbolAstScope> scope, SymbolAstContext& context, shared_ptr<ast::AstDeclaration> state)
		{
			AstDeclaration::Ptr astOp;
			switch (op)
			{
			case BinaryOperator::Concat:
				astOp = scope->opConcat;
				break;
			case BinaryOperator::Add:
				astOp = scope->opAdd;
				break;
			case BinaryOperator::Sub:
				astOp = scope->opSub;
				break;
			case BinaryOperator::Mul:
				astOp = scope->opMul;
				break;
			case BinaryOperator::Div:
				astOp = scope->opDiv;
				break;
			case BinaryOperator::IntDiv:
				astOp = scope->opIntDiv;
				break;
			case BinaryOperator::Mod:
				astOp = scope->opMod;
				break;
			case BinaryOperator::LT:
				astOp = scope->opLT;
				break;
			case BinaryOperator::GT:
				astOp = scope->opGT;
				break;
			case BinaryOperator::LE:
				astOp = scope->opLE;
				break;
			case BinaryOperator::GE:
				astOp = scope->opGE;
				break;
			case BinaryOperator::EQ:
				astOp = scope->opEQ;
				break;
			case BinaryOperator::NE:
				astOp = scope->opNE;
				break;
			case BinaryOperator::And:
				astOp = scope->opAnd;
				break;
			case BinaryOperator::Or:
				astOp = scope->opOr;
				break;
			}

			SymbolAstResult result;
			vector<AstExpression::Ptr> exprs;
			int exprStart = 0;
			
			result.MergeForExpression(first->GenerateAst(scope, context, state), context, exprs, exprStart, state);
			result.MergeForExpression(second->GenerateAst(scope, context, state), context, exprs, exprStart, state);

			auto stat = make_shared<AstExpressionStatement>();

			auto invoke = make_shared<AstInvokeExpression>();
			stat->expression = invoke;
			{
				auto ref = make_shared<AstReferenceExpression>();
				ref->reference = astOp;
				invoke->function = ref;
			}
			{
				auto arg = make_shared<AstReferenceExpression>();
				arg->reference = state;
				invoke->arguments.push_back(arg);
			}
			invoke->arguments.push_back(exprs[0]);
			invoke->arguments.push_back(exprs[1]);

			auto lambda = Expression::GenerateContinuationLambdaAst(scope, context, state);
			invoke->arguments.push_back(lambda);
			
			auto ast = make_shared<AstReferenceExpression>();
			ast->reference = lambda->arguments[1];

			result.AppendStatement(stat);
			return result.ReplaceValue(ast, lambda);
		}
		SymbolAstResult InvokeExpression::GenerateAst(shared_ptr<SymbolAstScope> scope, SymbolAstContext& context, shared_ptr<ast::AstDeclaration> state)
		{
			Expression::Ptr realFunction;
			Expression::List realArguments;
			bool invokeContinuation = false;
			if (auto ref = dynamic_pointer_cast<ReferenceExpression>(function))
			{
				switch (ref->symbol->target)
				{
				case GrammarSymbolTarget::Invoke:
					{
						realFunction = arguments[0];
						realArguments = dynamic_pointer_cast<ListExpression>(arguments[1])->elements;
					}
					break;
				case GrammarSymbolTarget::InvokeContinuation:
					{
						realFunction = arguments[0];
						realArguments = dynamic_pointer_cast<ListExpression>(arguments[1])->elements;
						invokeContinuation = true;
					}
					break;
				case GrammarSymbolTarget::NewTypeOfFields:
					{
						SymbolAstResult result;
						vector<AstExpression::Ptr> exprs;
						int exprStart = 0;
						for (auto expr : dynamic_pointer_cast<ListExpression>(arguments[1])->elements)
						{
							result.MergeForExpression(expr->GenerateAst(scope, context, state), context, exprs, exprStart, state);
						}

						auto ast = make_shared<AstNewTypeExpression>();
						ast->type = scope->GetType(dynamic_pointer_cast<ReferenceExpression>(arguments[0])->symbol);
						ast->fields = exprs;
						return result.ReplaceValue(ast);
					}
				case GrammarSymbolTarget::NewArray:
					{
						SymbolAstResult result = arguments[0]->GenerateAst(scope, context, state);
						auto ast = make_shared<AstNewArrayExpression>();
						ast->length = result.value;
						return result.ReplaceValue(ast);
					}
				case GrammarSymbolTarget::GetArrayItem:
					{
						SymbolAstResult result;
						vector<AstExpression::Ptr> exprs;
						int exprStart = 0;
						for (auto expr : arguments)
						{
							result.MergeForExpression(expr->GenerateAst(scope, context, state), context, exprs, exprStart, state);
						}

						auto ast = make_shared<AstArrayAccessExpression>();
						ast->target = exprs[1];
						ast->index = exprs[0];
						return result.ReplaceValue(ast);
					}
				case GrammarSymbolTarget::GetArrayLength:
					{
						SymbolAstResult result = arguments[0]->GenerateAst(scope, context, state);
						auto ast = make_shared<AstArrayLengthExpression>();
						ast->target = result.value;
						return result.ReplaceValue(ast);
					}
				case GrammarSymbolTarget::IsType:
					{
						SymbolAstResult result = arguments[0]->GenerateAst(scope, context, state);
						auto ast = make_shared<AstTestTypeExpression>();
						ast->target = result.value;
						ast->type = scope->GetType(dynamic_pointer_cast<ReferenceExpression>(arguments[1])->symbol);
						return result.ReplaceValue(ast);
					}
				case GrammarSymbolTarget::IsNotType:
					{
						SymbolAstResult result = arguments[0]->GenerateAst(scope, context, state);
						
						auto stat = make_shared<AstExpressionStatement>();

						auto invoke = make_shared<AstInvokeExpression>();
						stat->expression = invoke;
						{
							auto ref = make_shared<AstReferenceExpression>();
							ref->reference = scope->opNot;
							invoke->function = ref;
						}
						{
							auto arg = make_shared<AstReferenceExpression>();
							arg->reference = state;
							invoke->arguments.push_back(arg);
						}
						{
							auto arg = make_shared<AstTestTypeExpression>();
							arg->target = result.value;
							arg->type = scope->GetType(dynamic_pointer_cast<ReferenceExpression>(arguments[1])->symbol);
							invoke->arguments.push_back(arg);
						}

						auto lambda = Expression::GenerateContinuationLambdaAst(scope, context, state);
						invoke->arguments.push_back(lambda);
			
						auto ast = make_shared<AstReferenceExpression>();
						ast->reference = lambda->arguments[1];

						result.AppendStatement(stat);
						return result.ReplaceValue(ast, lambda);
					}
				case GrammarSymbolTarget::GetField:
					{
						SymbolAstResult result = arguments[1]->GenerateAst(scope, context, state);
						auto ast = make_shared<AstFieldAccessExpression>();
						ast->target = result.value;
						ast->composedFieldName = dynamic_pointer_cast<ArgumentExpression>(arguments[0])->name->GetComposedName();
						return result.ReplaceValue(ast);
					}
				}
			}

			if (!realFunction)
			{
				realFunction = function;
				realArguments = arguments;
			}

			SymbolAstResult result;
			vector<AstExpression::Ptr> exprs;
			int exprStart = 0;

			result.MergeForExpression(realFunction->GenerateAst(scope, context, state), context, exprs, exprStart, state);
			for (auto arg : realArguments)
			{
				result.MergeForExpression(arg->GenerateAst(scope, context, state), context, exprs, exprStart, state);
			}

			auto stat = make_shared<AstExpressionStatement>();

			auto invoke = make_shared<AstInvokeExpression>();
			stat->expression = invoke;
			auto it = exprs.begin();
			invoke->function = *it++;
			{
				auto ref = make_shared<AstReferenceExpression>();
				ref->reference = state;
				invoke->arguments.push_back(ref);
			}
			while (it != exprs.end())
			{
				invoke->arguments.push_back(*it++);
			}

			if (invokeContinuation)
			{
				auto ast = make_shared<AstLiteralExpression>();
				ast->literalName = AstLiteralName::Null;
				
				auto lambda = GenerateContinuationLambdaAst(scope, context, state);
				auto lambdaStat = make_shared<AstExpressionStatement>();
				lambdaStat->expression = lambda;
				
				result.AppendStatement(stat);
				result.AppendStatement(lambdaStat);
				return result.ReplaceValue(ast, lambda);
			}
			else
			{
				auto lambda = GenerateContinuationLambdaAst(scope, context, state);
				invoke->arguments.push_back(lambda);
			
				auto ast = make_shared<AstReferenceExpression>();
				ast->reference = lambda->arguments[1];

				result.AppendStatement(stat);
				return result.ReplaceValue(ast, lambda);
			}
		}
		SymbolAstResult BinaryExpression::GenerateAst(shared_ptr<SymbolAstScope> scope, SymbolAstContext& context, shared_ptr<ast::AstDeclaration> state)
		{
			AstBinaryOperator astOp = AstBinaryOperator::Concat;
			
			switch (op)
			{
			case BinaryOperator::Concat:
				astOp = AstBinaryOperator::Concat;
				break;
			case BinaryOperator::Add:
				astOp = AstBinaryOperator::Add;
				break;
			case BinaryOperator::Sub:
				astOp = AstBinaryOperator::Sub;
				break;
			case BinaryOperator::Mul:
				astOp = AstBinaryOperator::Mul;
				break;
			case BinaryOperator::Div:
				astOp = AstBinaryOperator::Div;
				break;
			case BinaryOperator::IntDiv:
				astOp = AstBinaryOperator::IntDiv;
				break;
			case BinaryOperator::Mod:
				astOp = AstBinaryOperator::Mod;
				break;
			case BinaryOperator::LT:
				astOp = AstBinaryOperator::LT;
				break;
			case BinaryOperator::GT:
				astOp = AstBinaryOperator::GT;
				break;
			case BinaryOperator::LE:
				astOp = AstBinaryOperator::LE;
				break;
			case BinaryOperator::GE:
				astOp = AstBinaryOperator::GE;
				break;
			case BinaryOperator::EQ:
				astOp = AstBinaryOperator::EQ;
				break;
			case BinaryOperator::NE:
				astOp = AstBinaryOperator::NE;
				break;
			case BinaryOperator::And:
				astOp = AstBinaryOperator::And;
				break;
			case BinaryOperator::Or:
				astOp = AstBinaryOperator::Or;
				break;
			}

			SymbolAstResult result;
			vector<AstExpression::Ptr> exprs;
			int exprStart = 0;
			
			result.MergeForExpression(first->GenerateAst(scope, context, state), context, exprs, exprStart, state);
			result.MergeForExpression(second->GenerateAst(scope, context, state), context, exprs, exprStart, state);

			auto ast = make_shared<AstBinaryExpression>();
			ast->op = astOp;
			ast->first = exprs[0];
			ast->second = exprs[1];
			return result.ReplaceValue(ast);
		}
		SymbolAstResult InvokeExpression::GenerateAst(shared_ptr<SymbolAstScope> scope, SymbolAstContext& context, shared_ptr<ast::AstDeclaration> state)
		{
			Expression::Ptr func;
			Expression::List args;

			if (auto ref = dynamic_pointer_cast<ReferenceExpression>(function))
			{
				switch (ref->symbol->target)
				{
				case GrammarSymbolTarget::Invoke:
					func = arguments[0];
					break;
				case GrammarSymbolTarget::InvokeWith:
					func = arguments[0];
					args = dynamic_pointer_cast<ListExpression>(arguments[1])->elements;
					break;
				case GrammarSymbolTarget::NewType:
					{
						auto ast = make_shared<AstNewTypeExpression>();
						ast->type = scope->GetType(dynamic_pointer_cast<ReferenceExpression>(arguments[0])->symbol, ast);
						return SymbolAstResult(ast);
					}
				case GrammarSymbolTarget::NewTypeOfFields:
					{
						SymbolAstResult result;
						vector<AstExpression::Ptr> exprs;
						int exprStart = 0;
						for (auto expr : dynamic_pointer_cast<ListExpression>(arguments[1])->elements)
						{
							result.MergeForExpression(expr->GenerateAst(scope, context, state), context, exprs, exprStart, state);
						}

						auto ast = make_shared<AstNewTypeExpression>();
						ast->type = scope->GetType(dynamic_pointer_cast<ReferenceExpression>(arguments[0])->symbol, ast);
						ast->fields = exprs;
						return result.ReplaceValue(ast);
					}
				case GrammarSymbolTarget::NewArray:
					{
						SymbolAstResult result = arguments[0]->GenerateAst(scope, context, state);
						auto ast = make_shared<AstNewArrayExpression>();
						ast->length = result.value;
						return result.ReplaceValue(ast);
					}
				case GrammarSymbolTarget::GetArrayItem:
					{
						SymbolAstResult result;
						vector<AstExpression::Ptr> exprs;
						int exprStart = 0;
						for (auto expr : arguments)
						{
							result.MergeForExpression(expr->GenerateAst(scope, context, state), context, exprs, exprStart, state);
						}

						auto ast = make_shared<AstArrayAccessExpression>();
						ast->target = exprs[1];
						ast->index = exprs[0];
						return result.ReplaceValue(ast);
					}
				case GrammarSymbolTarget::GetArrayLength:
					{
						SymbolAstResult result = arguments[0]->GenerateAst(scope, context, state);
						auto ast = make_shared<AstArrayLengthExpression>();
						ast->target = result.value;
						return result.ReplaceValue(ast);
					}
				case GrammarSymbolTarget::IsType:
					{
						SymbolAstResult result = arguments[0]->GenerateAst(scope, context, state);
						auto ast = make_shared<AstTestTypeExpression>();
						ast->target = result.value;
						ast->type = scope->GetType(dynamic_pointer_cast<ReferenceExpression>(arguments[1])->symbol, ast);
						return result.ReplaceValue(ast);
					}
				case GrammarSymbolTarget::IsNotType:
					{
						SymbolAstResult result = arguments[0]->GenerateAst(scope, context, state);
						auto ast = make_shared<AstTestTypeExpression>();
						ast->target = result.value;
						ast->type = scope->GetType(dynamic_pointer_cast<ReferenceExpression>(arguments[1])->symbol, ast);

						auto unary = make_shared<AstUnaryExpression>();
						unary->op = AstUnaryOperator::Not;
						unary->operand = ast;
						return result.ReplaceValue(unary);
					}
				case GrammarSymbolTarget::GetField:
					{
						SymbolAstResult result = arguments[1]->GenerateAst(scope, context, state);
						auto ast = make_shared<AstFieldAccessExpression>();
						ast->target = result.value;
						ast->composedFieldName = dynamic_pointer_cast<ArgumentExpression>(arguments[0])->name->GetComposedName();
						return result.ReplaceValue(ast);
					}
				}
			}
			if (!func)
			{
				func = function;
				args = arguments;
			}

			SymbolAstResult result;
			vector<AstExpression::Ptr> exprs;
			int exprStart = 0;

			result.MergeForExpression(func->GenerateAst(scope, context, state), context, exprs, exprStart, state);
			for (auto arg : args)
			{
				result.MergeForExpression(arg->GenerateAst(scope, context, state), context, exprs, exprStart, state);
			}

			auto stat = make_shared<AstExpressionStatement>();

			auto invoke = make_shared<AstInvokeExpression>();
			stat->expression = invoke;
			auto it = exprs.begin();
			invoke->function = *it++;
			{
				auto ref = make_shared<AstReferenceExpression>();
				ref->reference = state;
				invoke->arguments.push_back(ref);
			}
			while (it != exprs.end())
			{
				invoke->arguments.push_back(*it++);
			}

			auto lambda = GenerateContinuationLambdaAst(scope, context, state);
			invoke->arguments.push_back(lambda);
			
			auto ast = make_shared<AstReferenceExpression>();
			ast->reference = lambda->arguments[1];

			result.AppendStatement(stat);
			return result.ReplaceValue(ast, lambda);
		}