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 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); }); } }