private dynamic Expression(Expr ast)
        {
            var lhs = ast.Left;
            var rhs = ast.Right;

            switch (ast.Token.TokenType)
            {
                case TokenType.Equals:
                    if (lhs.AstType == AstTypes.ClassRef)
                    {
                        // a litle trickery here. create a copy of the class reference
                        // with everytihng up to the second to last item. this gives you
                        // the workign memory space that the very last item should sit in
                        // then lets execute this as if we are asking for the memory space
                        // and finally assign the very last symbol to the calculated memory
                        // space we got

                        var classRef = (lhs as ClassReference);

                        var lastItem = classRef.Deferences.Last();

                        var fakeRef = new ClassReference(classRef.ClassInstance,
                                                         classRef.Deferences.Take(classRef.Deferences.Count - 1)
                                                                 .ToList());

                        var space = GetValue(Exec(fakeRef));

                        Assign(lastItem, Exec(rhs), space);
                    }

                    else
                    {
                        ValueMemory itemSpace = Get(lhs);

                        Assign(lhs, Exec(rhs), itemSpace != null ? itemSpace.Memory : null);
                    }
                    return null;

                case TokenType.Word:
                    return Get(ast);

                case TokenType.Int:
                    return Convert.ToInt32(ast.Token.TokenValue);

                case TokenType.Float:
                    return Convert.ToDouble(ast.Token.TokenValue);

                case TokenType.QuotedString:
                    return ast.Token.TokenValue;

                case TokenType.Nil:
                    return TokenType.Nil;

                case TokenType.True:
                    return true;

                case TokenType.False:
                    return false;
            }

            if (TokenUtil.IsOperator(ast.Token))
            {
                return ApplyOperation(ast);
            }

            return null;
        }
        private dynamic ClassRefDo(ClassReference classReference)
        {
            var oldSpace = MemorySpaces.Current;

            var memorySpace = Get(classReference.ClassInstance).Value as MemorySpace;

            MemorySpaces.Current = memorySpace;

            try
            {
                if (classReference.Deferences.Count == 0)
                {
                    return memorySpace;
                }

                foreach (var deref in classReference.Deferences)
                {
                    // make sure that the last dereference knows how to pull
                    // its arguments, which are from the original memory space and not
                    // the relative class space. i.e. A.b.foo(x), x is loaded from the
                    // space that contains A, not from the space of b.

                    if (deref == classReference.Deferences.Last())
                    {
                        deref.CallingMemory = oldSpace;
                    }

                    var newSpace = GetValue(Exec(deref));

                    if (deref == classReference.Deferences.Last())
                    {
                        return newSpace;
                    }

                    MemorySpaces.Current = newSpace;
                }
            }
            finally
            {
                MemorySpaces.Current = oldSpace;
            }

            return null;
        }
        public void Visit(ClassReference ast)
        {
            if (!ResolvingTypes)
            {
                return;
            }

            var declaredSymbol = Resolve(ast.ClassInstance);

            if (declaredSymbol == null)
            {
                throw new UndefinedElementException(string.Format("Class instance '{0}' does not exist in current scope", ast.ClassInstance.Token.TokenValue));
            }

            var classScope = Resolve(declaredSymbol.Type.TypeName) as ClassSymbol;

            if (classScope == null)
            {
                classScope = Global.Resolve(declaredSymbol.Type.TypeName) as ClassSymbol;
            }

            var oldScope = Current;

            Current = classScope;

            foreach (var reference in ast.Deferences)
            {
                if (reference == ast.Deferences.Last())
                {
                    reference.CallingScope = oldScope;
                }

                reference.CurrentScope = Current;

                reference.IsPureDynamic = Current == null;

                reference.Visit(this);

                var field = Resolve(reference);

                if (field == null && !reference.IsPureDynamic)
                {
                    throw new InvalidSyntax(String.Format("Class {0} has no field named {1}", declaredSymbol.Type.TypeName, reference.Token.TokenValue));
                }

                if (field != null && field.Type.ExpressionType == ExpressionTypes.UserDefined)
                {
                    Current = Global.Resolve(field.Type.TypeName) as ClassSymbol;
                }
            }

            Current = oldScope;

            ast.AstSymbolType = ast.Deferences.Last().AstSymbolType;

            if (ast.AstSymbolType.ExpressionType == ExpressionTypes.Method)
            {
                try
                {
                    ast.AstSymbolType = (ast.AstSymbolType.Src as MethodDeclr).ReturnAst.AstSymbolType;
                }
                catch (Exception ex)
                {

                }
            }

            SetScope(ast);

            SetScope(ast.ClassInstance);
        }
 public void Visit(ClassReference ast)
 {
     Exec(ast);
 }
Exemplo n.º 5
0
 public void Visit(ClassReference ast)
 {
     throw new NotImplementedException();
 }