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>() )); })); }
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()); })); }
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); }
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); }
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); }
public FunctionDefinitionMarshaler(ByteCodeChunk chunk) { this.chunk = chunk; this.builder = chunk.BeginFunctionType(); this.builder.returnType = global::cflat.Marshal.TypeOf <R>(chunk); }