Esempio n. 1
0
        public override AstNode Visit(FixedVariableDecl node)
        {
            // Begin the node.
            builder.BeginNode(node);

            // Get the fixed local.
            LocalVariable local = node.GetVariable();

            // Get the value expression.
            Expression valueExpr = node.GetValueExpression();
            valueExpr.Accept(this);

            // Get the associated types.
            IChelaType type = node.GetNodeType();
            IChelaType coercionType = node.GetCoercionType();
            IChelaType valueType = valueExpr.GetNodeType();

            // Perform coercion.
            if(valueType != coercionType )
                Cast(node, valueExpr.GetNodeValue(), valueType, coercionType);

            // Pin references, cast pointers.
            if(coercionType.IsPointer())
            {
                // Cast the pointer.
                if(coercionType != type)
                    Cast(node, null, coercionType, type);

                // Store the pointer in a local.
                builder.CreateStoreLocal(local);
            }
            else
            {
                // References.
                valueType = DeReferenceType(coercionType);

                // Give a null value for null references.
                builder.CreateDup1();

                // Create the blocks for the comparison
                BasicBlock notNullBlock = CreateBasicBlock();
                notNullBlock.SetName("notNull");

                BasicBlock nullBlock = CreateBasicBlock();
                nullBlock.SetName("null");

                BasicBlock nullMerge = CreateBasicBlock();
                nullMerge.SetName("nullMerge");

                // Compare to null.
                builder.CreateLoadNull();
                builder.CreateCmpEQ();
                builder.CreateBr(nullBlock, notNullBlock);

                // Set the null block content.
                builder.SetBlock(nullBlock);
                builder.CreatePop();
                builder.CreateLoadNull();
                builder.CreateStoreLocal(local);
                builder.CreateJmp(nullMerge);

                // Set the not null content.
                builder.SetBlock(notNullBlock);

                // Use the first element of the array.
                if(valueType.IsArray())
                {
                    ArrayType array = (ArrayType)valueType;
                    for(int i = 0; i < array.GetDimensions(); ++i)
                        builder.CreateLoadUInt8(0);
                    builder.CreateLoadArraySlotAddr(array);

                    // Cast the result.
                    IChelaType slotType = PointerType.Create(array.GetValueType());
                    if(slotType != type)
                        Cast(node, null, slotType, type);
                }
                else
                    Error(node, "unsupported fixed object of type {0}.", valueType.GetName());

                // Store the value.
                builder.CreateStoreLocal(local);

                // Merge the results.
                builder.CreateJmp(nullMerge);
                builder.SetBlock(nullMerge);
            }

            // End.
            return builder.EndNode();
        }
Esempio n. 2
0
        public override AstNode Visit(FixedVariableDecl node)
        {
            // Get the variable type.
            IChelaType type = node.GetNodeType();

            // Create the variable.
            LocalVariable fixedVar = new LocalVariable(node.GetName(), (LexicalScope)currentScope, type);
            node.SetVariable(fixedVar);

            // Visit the value expression.
            Expression valueExpr = node.GetValueExpression();
            valueExpr.Accept(this);

            // Get the value type.
            IChelaType valueType = valueExpr.GetNodeType();

            // The value must be a reference or a pointer.
            if(!valueType.IsReference() && !valueType.IsPointer())
                Error(valueExpr, "the value expression must be a reference or a pointer.");

            if(valueType.IsPointer())
            {
                if(Coerce(node, type, valueType, valueExpr.GetNodeValue()) != type)
                    Error(valueExpr, "cannot convert {0} into {1}.", valueType.GetName(), type.GetName());

                // Coerce the value.
                node.SetCoercionType(type);
            }
            else
            {
                // Remove references.
                IChelaType refType = DeReferenceType(valueType);
                if(refType.IsReference())
                    refType = DeReferenceType(refType);

                // Only support arrays
                if(refType.IsArray())
                {
                    ArrayType array = (ArrayType)refType;
                    IChelaType pointerType = PointerType.Create(array.GetValueType());
                    if(Coerce(node, type, pointerType, null) != type)
                        Error(valueExpr, "cannot convert {0} into {1}.", pointerType.GetName(), type.GetName());
                }

                // Set the new coercion type.
                node.SetCoercionType(ReferenceType.Create(refType));
            }

            return node;
        }