コード例 #1
0
        public static bool AddFunction <A0, A1, A2, A3, R>(this CFlat self, string functionName, System.Func <A0, A1, A2, A3, R> function)
            where A0 : struct, IMarshalable
            where A1 : struct, IMarshalable
            where A2 : struct, IMarshalable
            where A3 : struct, IMarshalable
            where R : struct, IMarshalable
        {
            var builder = new FunctionTypeBuilder(self.chunk);

            builder.WithParam(Marshal.TypeOf <A0>(self.chunk));
            builder.WithParam(Marshal.TypeOf <A1>(self.chunk));
            builder.WithParam(Marshal.TypeOf <A2>(self.chunk));
            builder.WithParam(Marshal.TypeOf <A3>(self.chunk));
            builder.returnType = Marshal.TypeOf <R>(self.chunk);
            return(FinishAddFunction(self, builder, functionName, (vm, top) =>
            {
                var functionInterface = new FunctionInterface(vm, top);
                FunctionInterface.Return(vm, function(
                                             functionInterface.Arg <A0>(),
                                             functionInterface.Arg <A1>(),
                                             functionInterface.Arg <A2>(),
                                             functionInterface.Arg <A3>()
                                             ));
            }));
        }
コード例 #2
0
        public static bool AddFunction <R>(this CFlat self, string functionName, System.Func <R> function)
            where R : struct, IMarshalable
        {
            var builder = new FunctionTypeBuilder(self.chunk);

            builder.returnType = Marshal.TypeOf <R>(self.chunk);
            return(FinishAddFunction(self, builder, functionName, (vm, top) =>
            {
                FunctionInterface.Return(vm, function());
            }));
        }
コード例 #3
0
        private static bool FinishAddFunction(CFlat self, FunctionTypeBuilder builder, string functionName, NativeFunction.Callback function)
        {
            var result = builder.Build(out var typeIndex);

            if (!self.compiler.io.CheckFunctionBuild(result, new Slice()))
            {
                return(false);
            }

            self.chunk.nativeFunctions.PushBack(new NativeFunction(
                                                    functionName,
                                                    typeIndex,
                                                    builder.returnType.GetSize(self.chunk),
                                                    function
                                                    ));
            return(true);
        }
コード例 #4
0
ファイル: TypeTests.cs プロジェクト: McJones/YarnSpinner
        public void TestFunctionTypeBuilderCanBuildTypes()
        {
            // Given
            var expectedFunctionType = new FunctionType();

            expectedFunctionType.ReturnType = BuiltinTypes.String;
            expectedFunctionType.AddParameter(BuiltinTypes.String);
            expectedFunctionType.AddParameter(BuiltinTypes.Number);

            var functionType = new FunctionTypeBuilder()
                               .WithParameter(BuiltinTypes.String)
                               .WithParameter(BuiltinTypes.Number)
                               .WithReturnType(BuiltinTypes.String)
                               .FunctionType;

            // Then
            Assert.Equal(expectedFunctionType.Parameters.Count, functionType.Parameters.Count);
            Assert.Equal(expectedFunctionType.Parameters[0], functionType.Parameters[0]);
            Assert.Equal(expectedFunctionType.Parameters[1], functionType.Parameters[1]);
            Assert.Equal(expectedFunctionType.ReturnType, functionType.ReturnType);
        }
コード例 #5
0
        public static int EndFunctionDeclaration(this CompilerIO self, FunctionTypeBuilder builder, Slice slice, bool isPublic, bool hasBody)
        {
            var name          = CompilerHelper.GetSlice(self, slice);
            var result        = builder.Build(out var index);
            var functionIndex = -1;

            if (self.CheckFunctionBuild(result, slice))
            {
                switch (self.chunk.AddFunction(name, isPublic, index, hasBody, slice, self.functionsStartIndex, out functionIndex))
                {
                case ByteCodeChunk.AddFunctionResult.AlreadyDefined:
                    self.AddSoftError(slice, "Function '{0}' is already defined", name);
                    break;

                case ByteCodeChunk.AddFunctionResult.VisibilityMismatch:
                {
                    if (self.ResolveToFunctionIndex(slice, out int prototypeIndex))
                    {
                        var prototypeIsPublic = self.chunk.functions.buffer[prototypeIndex].isPublic;

                        self.AddSoftError(
                            slice,
                            "Visibility mismatch between function '{0}' prototype and its body. Expected {1}. Got {2}",
                            name,
                            prototypeIsPublic ? "'pub'" : "no 'pub'",
                            isPublic ? "'pub'" : "no 'pub'"
                            );
                    }
                    else
                    {
                        self.AddSoftError(slice, "Visibility mismatch between function '{0}' prototype and its body", name);
                    }
                    break;
                }

                case ByteCodeChunk.AddFunctionResult.TypeMismatch:
                {
                    if (self.ResolveToFunctionIndex(slice, out int prototypeIndex))
                    {
                        var typeIndex     = self.chunk.functions.buffer[prototypeIndex].typeIndex;
                        var prototypeType = new ValueType(TypeKind.Function, typeIndex);
                        var functionType  = new ValueType(TypeKind.Function, index);

                        self.AddSoftError(
                            slice,
                            "Type mismatch between function '{0}' prototype and its body. Expected {1}. Got {2}",
                            name,
                            prototypeType.ToString(self.chunk),
                            functionType.ToString(self.chunk)
                            );
                    }
                    else
                    {
                        self.AddSoftError(slice, "Type mismatch between function '{0}' prototype and its body", name);
                    }
                    break;
                }

                default:
                    break;
                }
            }

            if (functionIndex < 0)
            {
                functionIndex = self.chunk.functions.count;
                if (self.chunk.functionTypes.count < ushort.MaxValue)
                {
                    self.chunk.functionTypes.PushBack(new FunctionType(new Slice(), new ValueType(TypeKind.Unit), 0));
                }
                var typeIndex = self.chunk.functionTypes.count - 1;

                self.chunk.functions.PushBack(new Function(name, isPublic, -slice.index, (ushort)typeIndex));
            }

            return(functionIndex);
        }
コード例 #6
0
ファイル: Marshal.cs プロジェクト: cflat-lang/cflat
 public FunctionDefinitionMarshaler(ByteCodeChunk chunk)
 {
     this.chunk              = chunk;
     this.builder            = chunk.BeginFunctionType();
     this.builder.returnType = global::cflat.Marshal.TypeOf <R>(chunk);
 }