private void InvokeNativeFunction(FunctionDeclarationNode currentFunction) { var nativeArguments = CurrentContextScopeVariables.Select(variable => variable.Value).ToArray(); currentFunction.NativeBody.DynamicInvoke(nativeArguments); CurrentContextScopeVariables.Add(new Variable { Name = "$return", Value = 0 }); }
private List <Variable> GetCurrentVariablesInScope() { if (CurrentContextScopeVariables != null) { return(CurrentContextScopeVariables.Concat(GlobalVariables).ToList()); } else { return(GlobalVariables); } }
private Variable CreateFunctionCall(FunctionCallExpressionNode functionCallNode, FunctionDeclarationNode currentFunction) { //Create function scope variables var functionArgumentVariables = new List <Variable>(); var functionCallArguments = functionCallNode.Arguments.ToList(); var functionSigArguments = currentFunction.Parameters.ToList(); //Create var createdArgumentVariables = functionSigArguments.Zip(functionCallArguments, (sigArg, callArg) => { var outputVariable = new Variable { Name = sigArg.Name, Value = EvaluateExpression(callArg) }; return(outputVariable); }); functionArgumentVariables.AddRange(createdArgumentVariables); FunctionScopeVariables.Push(functionArgumentVariables); if (currentFunction.BodyType == FunctionBodyType.FlameScript) { ExecuteNodes(currentFunction.SubNodes.ToList()); } else if (currentFunction.BodyType == FunctionBodyType.Native) { InvokeNativeFunction(currentFunction); } var returnedVariable = CurrentContextScopeVariables.Where(variable => variable.Name == "$return").ToList()[0]; FunctionScopeVariables.Pop(); return(returnedVariable); }
private void ExecuteNodes(List <AstNode> nonFunctionDeclarationNodes) { foreach (var nodeToExecute in nonFunctionDeclarationNodes) { TypeSwitch.On(nodeToExecute) .Case((VariableDeclarationNode variableDeclarationNode) => { var newVar = new Variable { Name = variableDeclarationNode.Name, Value = EvaluateExpression(variableDeclarationNode.InitialValueExpression) }; if (CurrentVariableScope == VariableScope.Global) { GlobalVariables.Add(newVar); } else { CurrentContextScopeVariables.Add(newVar); } if (variableDeclarationNode.Type == VariableType.Table) { newVar.Value = new Expando(); } }) .Case((TableMemberInvocationNode tableMemberInvocationNode) => { var currentVariable = GetReferencedVariable(tableMemberInvocationNode.TableQualifier.Name); // Take off the last member var memberChainList = tableMemberInvocationNode.TableQualifier.MemberChain.ToList(); var lastMemberInChain = memberChainList.Last(); memberChainList.Remove(lastMemberInChain); dynamic intermediateMember = currentVariable.Value; //Take all except the last var remainingMembers = memberChainList; foreach (var member in remainingMembers) { intermediateMember = intermediateMember[member]; } var methodToInvoke = intermediateMember[lastMemberInChain]; //TODO: Invoke method with dynamic parameters var methodInfo = intermediateMember.GetType().GetMethod(methodToInvoke); }) .Case((FunctionCallExpressionNode functionCallNode) => { var currentFunction = GetReferencedFunction(functionCallNode); //This will be a call without regard to return type CreateFunctionCall(functionCallNode, currentFunction); }) .Case((ReturnStatementNode returnStatementNode) => { //If there is a return statement, we're obviously in a function scope CurrentContextScopeVariables.Add(new Variable { Name = "$return", Value = EvaluateExpression(returnStatementNode.ValueExpression) ?? null }); }) .Case((BinaryOperationNode binaryOperationNode) => { DoBinaryOperation(binaryOperationNode); }) .Case((IfStatementNode ifStatementNode) => { //This only runs if the condition is true if (EvaluateToBoolean(EvaluateExpression(ifStatementNode.Condition))) { //Condition is true, execute conditional nodes ExecuteNodes(ifStatementNode.SubNodes.ToList()); } }) .Case((WhileLoopNode whileLoopNode) => { while (EvaluateToBoolean(EvaluateExpression(whileLoopNode.Condition))) { //Condition is true, execute conditional nodes ExecuteNodes(whileLoopNode.SubNodes.ToList()); } }) .Case((TableAssignmentNode tableAssignmentNode) => { var currentVariable = GetReferencedVariable(tableAssignmentNode.TableQualifier.Name); // Take off the last member var memberChainList = tableAssignmentNode.TableQualifier.MemberChain.ToList(); var lastMemberInChain = memberChainList.Last(); memberChainList.Remove(lastMemberInChain); dynamic intermediateMember = currentVariable.Value; //Take all except the last var remainingMembers = memberChainList; foreach (var member in remainingMembers) { intermediateMember = intermediateMember[member]; } intermediateMember[lastMemberInChain] = EvaluateExpression(tableAssignmentNode.ValueExpression); }) .Case((VariableAssignmentNode variableAssignmentNode) => { var currentVariable = GetReferencedVariable(variableAssignmentNode.VariableName); currentVariable.Value = EvaluateExpression(variableAssignmentNode.ValueExpression); }); } }