private void VariableDeclaration(VarDeclrAst varDeclrAst)
        {
            if (varDeclrAst.VariableValue == null)
            {
                var symbol = varDeclrAst.CurrentScope.Resolve(varDeclrAst.VariableName.Token.TokenValue);

                var space = MemorySpaces.Current;

                space.Define(symbol.Name, TokenType.Nil);

                return;
            }

            var variableValue = varDeclrAst.VariableValue.ConvertedExpression ?? varDeclrAst.VariableValue;

            // if the rhs of a variable is not a method, then execute it,
            if (variableValue.AstType != AstTypes.MethodDeclr)
            {
                var value = GetValue(Exec(variableValue));

                if (value != null)
                {
                    var symbol = varDeclrAst.CurrentScope.Resolve(varDeclrAst.VariableName.Token.TokenValue);

                    var space = MemorySpaces.Current;

                    if (variableValue.IsLink)
                    {
                        space.Link(symbol.Name, variableValue.Token.TokenValue);
                    }
                    else
                    {
                        space.Define(symbol.Name, value);
                    }
                }
            }
            else
            {
                var symbol = varDeclrAst.CurrentScope.Resolve(varDeclrAst.VariableName.Token.TokenValue);

                var resolvedMethod = varDeclrAst.CurrentScope.Resolve(variableValue.Token.TokenValue) as MethodSymbol;

                // make sure to create a NEW method symbol. this way each time we declare this item
                // it will create a local copy and get its own memory space for closures.
                // if we shared the same method symbol then all instances of the same declaration would share the memory space,
                // which may not be what we want given class instances having their own spaces

                var localMethodCopy = new MethodSymbol(resolvedMethod.Name, resolvedMethod.Type,
                                                       resolvedMethod.MethodDeclr);

                var space = MemorySpaces.Current;

                if (variableValue is LambdaDeclr)
                {
                    localMethodCopy.Environment = space;
                }

                space.Define(symbol.Name, localMethodCopy);
            }
        }
        private LambdaDeclr CreateCurriedMethod(FuncInvoke ast, MethodSymbol functionType)
        {
            var srcMethod = functionType.MethodDeclr;

            var fixedAssignments = new List <VarDeclrAst>();

            var count = 0;

            foreach (var argValue in ast.Arguments)
            {
                var srcArg = srcMethod.Arguments[count] as VarDeclrAst;

                var token = new Token(srcArg.DeclarationType.Token.TokenType, argValue.Token.TokenValue);

                var declr = new VarDeclrAst(token, srcArg.Token, new Expr(argValue.Token));

                // if we're creating a curry using a variable then we need to resolve the variable type
                // otherwise we can make a symbol for the literal
                var newArgType = argValue.Token.TokenType == TokenType.Word ?
                                 ast.CurrentScope.Resolve(argValue).Type
                                    :   ScopeUtil.CreateSymbolType(argValue);

                // create a symbol type for the target we're invoking on so we can do type checking
                var targetArgType = ScopeUtil.CreateSymbolType(srcArg.DeclarationType);

                if (!TokenUtil.EqualOrPromotable(newArgType, targetArgType))
                {
                    throw new InvalidSyntax(String.Format("Cannot pass argument {0} of type {1} to partial function {2} as argument {3} of type {4}",
                                                          argValue.Token.TokenValue,
                                                          newArgType.TypeName,
                                                          srcMethod.MethodName.Token.TokenValue,
                                                          srcArg.VariableName.Token.TokenValue,
                                                          targetArgType.TypeName));
                }

                fixedAssignments.Add(declr);

                count++;
            }

            var newBody = fixedAssignments.Concat(srcMethod.Body.ScopedStatements).ToList();

            var curriedMethod = new LambdaDeclr(srcMethod.Arguments.Skip(ast.Arguments.Count).ToList(), new ScopeDeclr(newBody));

            SetScope(curriedMethod);

            return(curriedMethod);
        }
        public void Visit(VarDeclrAst ast)
        {
            if (ast.DeclarationType != null)
            {
                ast.DeclarationType.Visit(this);
            }

            ast.VariableName.Visit(this);

            if (ast.VariableValue != null)
            {
                Console.WriteLine("Equals");

                ast.VariableValue.Visit(this);
            }
        }
 public void Visit(VarDeclrAst ast)
 {
     Exec(ast);
 }
        public void Visit(VarDeclrAst ast)
        {
            var isVar = ast.DeclarationType.Token.TokenType == TokenType.Infer;

            if (ast.DeclarationType != null && !isVar)
            {
                var symbol = ScopeUtil.DefineUserSymbol(ast.DeclarationType, ast.VariableName);

                symbol.IsArray = ast is ArrayDeclrAst;

                DefineToScope(ast, symbol);

                ast.AstSymbolType = symbol.Type;
            }

            if (ast.VariableValue == null && isVar)
            {
                var symbol = ScopeUtil.DefineUserSymbol(ast.DeclarationType, ast.VariableName);

                DefineToScope(ast, symbol);

                ast.AstSymbolType = symbol.Type;
            }

            else if (ast.VariableValue != null)
            {
                ast.VariableValue.Visit(this);

                // if its type inferred, determine the declaration by the value's type
                if (isVar)
                {
                    // if the right hand side is a method declaration, make sure to track the source value
                    // this way we can reference it later to determine not only that this is a method type, but what
                    // is the expected return value for static type checking later

                    var val = ast.VariableValue.ConvertedExpression ?? ast.VariableValue;

                    ast.AstSymbolType = val is MethodDeclr
                                            ? new BuiltInType(ExpressionTypes.Method, val)
                                            : val.AstSymbolType;

                    var symbol = ScopeUtil.DefineUserSymbol(ast.AstSymbolType, ast.VariableName);

                    symbol.IsArray = ast is ArrayDeclrAst;

                    DefineToScope(ast, symbol);
                }
                else if (ResolvingTypes)
                {
                    var declaredType = ScopeUtil.CreateSymbolType(ast.DeclarationType);

                    var value = ast.VariableValue.ConvertedExpression ?? ast.VariableValue;

                    ReturnAst returnType = null;

                    // when we're resolving types check if the rhs is a function invoke. if it is, see
                    // what the return value of the src expression is so we can make sure that the
                    // lhs and the rhs match.
                    try
                    {
                        returnType =
                            value is FuncInvoke
                                ? ((value as FuncInvoke).AstSymbolType) != null
                                      ? ((value as FuncInvoke).AstSymbolType.Src as MethodDeclr).ReturnAst
                                      : null
                                : null;
                    }
                    catch
                    {
                    }

                    value = returnType != null ? returnType.ReturnExpression : value;

                    if (!TokenUtil.EqualOrPromotable(value.AstSymbolType.ExpressionType, declaredType.ExpressionType))
                    {
                        throw new InvalidSyntax(String.Format("Cannot assign {0} of type {1} to {2}", ast.VariableValue,
                                                              value.AstSymbolType.ExpressionType,
                                                              declaredType.ExpressionType));
                    }
                }
            }

            SetScope(ast);
        }