public void EmitPtr(IBlockContext context)
 {
     EmitLoad(context);
     using ITempBlockVariable tempLocal =
               context.MakeTempVariable(FieldType.UnderlyingType(context.ModuleContext));
     tempLocal.EmitStore(context);
     tempLocal.EmitLoadPtr(context);
 }
Exemplo n.º 2
0
        public void EmitAssign(IBlockContext context, IBlockVariable variable, Node target)
        {
            using ITempBlockVariable tempRight = context.MakeTempVariable(sourceType);
            tempRight.EmitStore(context);
            context.IL.Emit(OpCodes.Pop); // Left side is just the variable we are about to override

            variable.EmitLoadPtr(context);
            EmitAssignToPtr(context, tempRight);
        }
Exemplo n.º 3
0
        public override void EmitCode(IBlockContext context, bool dropResult)
        {
            if (dropResult)
            {
                return;
            }

            using ITempBlockVariable tempVariable = context.MakeTempVariable(BuiltinType.Range);
            EmitStore(context, tempVariable, false);
        }
Exemplo n.º 4
0
        public override void EmitCode(IBlockContext context, bool dropResult)
        {
            if (dropResult)
            {
                return;
            }

            TupleType tupleHint = ResultType(context) as TupleType;

            using ITempBlockVariable tempVariable = context.MakeTempVariable(tupleHint ?? DeriveType(context));
            EmitStore(context, tempVariable, false);
        }
Exemplo n.º 5
0
        public void EmitConvert(IBlockContext context)
        {
            using ITempBlockVariable valueTemp = context.MakeTempVariable(sourceType);
            valueTemp.EmitStore(context);

            Type generatedType = targetType.GeneratedType(context.ModuleContext);

            using ITempLocalRef someResult = context.IL.TempLocal(generatedType);
            someResult.EmitLoadPtr(context);
            EmitAssignToPtr(context, valueTemp);
            someResult.EmitLoad(context);
        }
Exemplo n.º 6
0
        // ---------------- IAssignEmitter -----------------
        public void EmitAssign(IBlockContext context, IBlockVariable variable, Expression expression, bool dropResult)
        {
            using ITempBlockVariable valueTemp = context.MakeTempVariable(sourceType);
            expression.EmitStore(context, valueTemp, true);

            variable.EmitLoadPtr(context);
            EmitAssignToPtr(context, valueTemp);
            if (!dropResult)
            {
                variable.EmitLoad(context);
            }
        }
Exemplo n.º 7
0
        /// <summary>
        /// Variant of the Emit when a pointer to the result of the expression is required, rather
        /// then the value itself.
        /// I.e. EmitPtr will leave a pointer on the stack where the result is stored.
        /// </summary>
        public virtual void EmitPtr(IBlockContext context)
        {
            using ITempBlockVariable tempLocal =
                      context.MakeTempVariable(ResultType(context).UnderlyingType(context.ModuleContext));
            EmitStore(context, tempLocal, true);

            if (context.HasErrors)
            {
                return;
            }

            tempLocal.EmitLoadPtr(context);
        }
Exemplo n.º 8
0
        // ---------------- IOperatorEmitter ----------------
        public void EmitCode(IBlockContext context, Node target)
        {
            using ITempBlockVariable tempRight = context.MakeTempVariable(sourceType);
            tempRight.EmitStore(context);

            Type generatedType = targetType.GeneratedType(context.ModuleContext);

            using ITempLocalRef someResult = context.IL.TempLocal(generatedType);
            someResult.EmitStore(context);

            someResult.EmitLoadPtr(context);
            EmitAssignToPtr(context, tempRight);
            someResult.EmitLoad(context);
        }
Exemplo n.º 9
0
        public void EmitAssign(IBlockContext context, IBlockVariable variable, Expression expression, bool dropResult)
        {
            Type generatedType = optionType.GeneratedType(context.ModuleContext);

            using ITempBlockVariable valueTemp =
                      context.MakeTempVariable(optionType.elementType.UnderlyingType(context.ModuleContext));
            optionType.elementType.AssignFrom(context.ModuleContext, otherType)
            .EmitAssign(context, valueTemp, expression, true);

            variable.EmitLoadPtr(context);
            context.IL.Emit(OpCodes.Dup);
            context.IL.Emit(OpCodes.Initobj, generatedType, 1, 0);
            context.IL.Emit(OpCodes.Dup);
            context.IL.Emit(OpCodes.Ldc_I4_1);
            context.IL.Emit(OpCodes.Stfld, generatedType.GetField("defined"));
            valueTemp.EmitLoad(context);
            context.IL.Emit(OpCodes.Stfld, generatedType.GetField("value"));
            if (!dropResult)
            {
                variable.EmitLoad(context);
            }
        }
Exemplo n.º 10
0
        public override void EmitCode(IBlockContext context, bool dropResult)
        {
            TO2Type             valueType   = expression.ResultType(context);
            TO2Type             targetType  = target.ResultType(context);
            IIndexAccessEmitter indexAccess = targetType.AllowedIndexAccess(context.ModuleContext, indexSpec);

            if (indexAccess == null)
            {
                context.AddError(new StructuralError(
                                     StructuralError.ErrorType.NoIndexAccess,
                                     $"Type '{targetType.Name}' does not support access by index",
                                     Start,
                                     End
                                     ));
                return;
            }

            if (target is IAssignContext assignContext)
            {
                if (assignContext.IsConst(context))
                {
                    context.AddError(new StructuralError(
                                         StructuralError.ErrorType.NoSuchField,
                                         $"Type '{targetType.Name}' elements can not be set on a read-only variable",
                                         Start,
                                         End
                                         ));
                    return;
                }
            }
            else
            {
                context.AddError(new StructuralError(
                                     StructuralError.ErrorType.CoreGeneration,
                                     $"Index assign '{targetType.Name}'.'{indexSpec}' on invalid target expression",
                                     Start,
                                     End
                                     ));
                return;
            }

            if (op == Operator.Assign)
            {
                if (indexAccess.RequiresPtr)
                {
                    target.EmitPtr(context);
                }
                else
                {
                    target.EmitCode(context, false);
                }

                if (context.HasErrors)
                {
                    return;
                }

                if (!dropResult)
                {
                    using ITempBlockVariable tmpResult =
                              context.MakeTempVariable(indexAccess.TargetType.UnderlyingType(context.ModuleContext));
                    indexAccess.EmitStore(context, subContext => {
                        expression.EmitCode(subContext, false);
                        indexAccess.TargetType.AssignFrom(subContext.ModuleContext, valueType)
                        .EmitConvert(subContext);

                        context.IL.Emit(OpCodes.Dup);
                        // ReSharper disable once AccessToDisposedClosure
                        tmpResult.EmitStore(subContext);
                    });

                    tmpResult.EmitLoad(context);
                }
                else
                {
                    indexAccess.EmitStore(context, subContext => {
                        expression.EmitCode(subContext, false);
                        indexAccess.TargetType.AssignFrom(subContext.ModuleContext, valueType).EmitConvert(subContext);
                    });
                }
            }
            else
            {
                IOperatorEmitter operatorEmitter = indexAccess.TargetType.AllowedSuffixOperators(context.ModuleContext)
                                                   .GetMatching(context.ModuleContext, op, valueType);

                if (operatorEmitter == null)
                {
                    context.AddError(new StructuralError(
                                         StructuralError.ErrorType.IncompatibleTypes,
                                         $"Index assign '{targetType.Name}'.'{indexSpec}': Cannot {op} a {indexAccess.TargetType} with a {valueType}",
                                         Start,
                                         End
                                         ));
                    return;
                }

                expression.Prepare(context);

                if (indexAccess.RequiresPtr)
                {
                    target.EmitPtr(context);
                }
                else
                {
                    target.EmitCode(context, false);
                }

                if (context.HasErrors)
                {
                    return;
                }

                if (!dropResult)
                {
                    using ITempBlockVariable tmpResult =
                              context.MakeTempVariable(indexAccess.TargetType.UnderlyingType(context.ModuleContext));
                    indexAccess.EmitStore(context, subContext => {
                        if (indexAccess.RequiresPtr)
                        {
                            target.EmitPtr(context);
                        }
                        else
                        {
                            target.EmitCode(context, false);
                        }

                        indexAccess.EmitLoad(context);
                        expression.EmitCode(subContext, false);

                        operatorEmitter.OtherType.AssignFrom(context.ModuleContext, valueType).EmitConvert(context);
                        operatorEmitter.EmitCode(context, this);

                        context.IL.Emit(OpCodes.Dup);
                        // ReSharper disable once AccessToDisposedClosure
                        tmpResult.EmitStore(subContext);
                    });

                    tmpResult.EmitLoad(context);
                }
                else
                {
                    indexAccess.EmitStore(context, subContext => {
                        if (indexAccess.RequiresPtr)
                        {
                            target.EmitPtr(context);
                        }
                        else
                        {
                            target.EmitCode(context, false);
                        }

                        indexAccess.EmitLoad(context);
                        expression.EmitCode(subContext, false);

                        operatorEmitter.OtherType.AssignFrom(context.ModuleContext, valueType).EmitConvert(context);
                        operatorEmitter.EmitCode(context, this);
                    });
                }
            }
        }
Exemplo n.º 11
0
        public override void EmitCode(IBlockContext context, bool dropResult)
        {
            TO2Type             targetType  = target.ResultType(context);
            IFieldAccessEmitter fieldAccess =
                targetType.FindField(context.ModuleContext, fieldName)?.Create(context.ModuleContext);
            TO2Type valueType = expression.ResultType(context);

            if (fieldAccess == null)
            {
                context.AddError(new StructuralError(
                                     StructuralError.ErrorType.NoSuchField,
                                     $"Type '{targetType.Name}' does not have a field '{fieldName}'",
                                     Start,
                                     End
                                     ));
                return;
            }

            if (!fieldAccess.CanStore)
            {
                context.AddError(new StructuralError(
                                     StructuralError.ErrorType.NoSuchField,
                                     $"Type '{targetType.Name}' field '{fieldName}' is read-only",
                                     Start,
                                     End
                                     ));
                return;
            }

            if (target is IAssignContext assignContext)
            {
                if (fieldAccess.RequiresPtr && assignContext.IsConst(context))
                {
                    context.AddError(new StructuralError(
                                         StructuralError.ErrorType.NoSuchField,
                                         $"Type '{targetType.Name}' field '{fieldName}' can not be set on a read-only variable",
                                         Start,
                                         End
                                         ));
                    return;
                }
            }
            else
            {
                context.AddError(new StructuralError(
                                     StructuralError.ErrorType.CoreGeneration,
                                     $"Field assign '{targetType.Name}'.'{fieldName}' on invalid target expression",
                                     Start,
                                     End
                                     ));
                return;
            }

            if (!fieldAccess.FieldType.IsAssignableFrom(context.ModuleContext, valueType))
            {
                context.AddError(new StructuralError(
                                     StructuralError.ErrorType.IncompatibleTypes,
                                     $"Type '{targetType.Name}' field '{fieldName}' is of type {fieldAccess.FieldType} but is assigned to {valueType}",
                                     Start,
                                     End
                                     ));
                return;
            }

            if (op == Operator.Assign)
            {
                if (fieldAccess.RequiresPtr)
                {
                    target.EmitPtr(context);
                }
                else
                {
                    target.EmitCode(context, false);
                }

                if (context.HasErrors)
                {
                    return;
                }

                expression.EmitCode(context, false);
                fieldAccess.FieldType.AssignFrom(context.ModuleContext, valueType).EmitConvert(context);

                if (!dropResult)
                {
                    using ITempBlockVariable tmpResult = context.MakeTempVariable(fieldAccess.FieldType);

                    context.IL.Emit(OpCodes.Dup);
                    tmpResult.EmitStore(context);

                    fieldAccess.EmitStore(context);

                    tmpResult.EmitLoad(context);
                }
                else
                {
                    fieldAccess.EmitStore(context);
                }
            }
            else
            {
                IOperatorEmitter operatorEmitter = fieldAccess.FieldType.AllowedSuffixOperators(context.ModuleContext)
                                                   .GetMatching(context.ModuleContext, op, valueType);

                if (operatorEmitter == null)
                {
                    context.AddError(new StructuralError(
                                         StructuralError.ErrorType.IncompatibleTypes,
                                         $"Type '{targetType.Name}' field '{fieldName}': Cannot {op} a {fieldAccess.FieldType} with a {valueType}",
                                         Start,
                                         End
                                         ));
                    return;
                }

                expression.Prepare(context);

                if (fieldAccess.RequiresPtr)
                {
                    target.EmitPtr(context);
                }
                else
                {
                    target.EmitCode(context, false);
                }

                if (fieldAccess.RequiresPtr)
                {
                    target.EmitPtr(context);
                }
                else
                {
                    target.EmitCode(context, false);
                }

                if (context.HasErrors)
                {
                    return;
                }

                fieldAccess.EmitLoad(context);
                expression.EmitCode(context, false);
                operatorEmitter.OtherType.AssignFrom(context.ModuleContext, valueType).EmitConvert(context);
                operatorEmitter.EmitCode(context, this);

                if (!dropResult)
                {
                    using ITempBlockVariable tmpResult = context.MakeTempVariable(fieldAccess.FieldType);

                    context.IL.Emit(OpCodes.Dup);
                    tmpResult.EmitStore(context);

                    fieldAccess.EmitStore(context);

                    tmpResult.EmitLoad(context);
                }
                else
                {
                    fieldAccess.EmitStore(context);
                }
            }
        }