private static FLScriptData LoadScriptData(string file, CLBufferInfo inBuffer, int width, int height, int depth, int channelCount, KernelDatabase db, Dictionary <string, FLFunctionInfo> funcs) { Logger.Log("Loading Script Data for File: " + file, DebugChannel.Log | DebugChannel.OpenFL | DebugChannel.IO, 6); FLScriptData ret = new FLScriptData(LoadSource(file, channelCount)); ret.Defines.Add(InputBufferName, inBuffer); Logger.Log("Parsing Texture Defines for File: " + file, DebugChannel.Log | DebugChannel.OpenFL | DebugChannel.IO, 5); ParseDefines(DefineKey, DefineTexture, ret.Source, ret.Defines, width, height, depth, channelCount, db); Logger.Log("Parsing Script Defines for File: " + file, DebugChannel.Log | DebugChannel.OpenFL | DebugChannel.IO, 5); ParseDefines(ScriptDefineKey, DefineScript, ret.Source, ret.Defines, width, height, depth, channelCount, db); Logger.Log("Parsing JumpLocations for File: " + file, DebugChannel.Log | DebugChannel.OpenFL | DebugChannel.IO, 5); ret.JumpLocations = ParseJumpLocations(ret.Source); Logger.Log("Parsing Instruction Data for File: " + file, DebugChannel.Log | DebugChannel.OpenFL | DebugChannel.IO, 5); foreach (string line in ret.Source) { Logger.Log("Parsing Instruction Data for Line: " + line, DebugChannel.Log | DebugChannel.OpenFL | DebugChannel.IO, 3); FLInstructionData data = GetInstructionData(line, ret.Defines, ret.JumpLocations, funcs, db); Logger.Log("Parsed Instruction Data: " + Enum.GetName(typeof(FLInstructionType), data.InstructionType), DebugChannel.Log | DebugChannel.OpenFL | DebugChannel.IO, 2); ret.ParsedSource.Add(data); } return(ret); }
private FLScriptData LoadScriptData(CLAPI instance, string file, CLBufferInfo inBuffer, int width, int height, int depth, int channelCount, KernelDatabase db, Dictionary <string, FLInterpreterFunctionInfo> funcs) { Logger.Log(DebugChannel.Log | DebugChannel.OpenFL, Verbosity.Level6, "Loading Script Data for File: " + file); FLScriptData ret = new FLScriptData(LoadSource(file, channelCount)); ret.Defines.Add(INPUT_BUFFER_NAME, inBuffer); Logger.Log(DebugChannel.Log | DebugChannel.OpenFL, Verbosity.Level5, "Parsing Texture Defines for File: " + file); ParseDefines(instance, DEFINE_KEY, DefineTexture, ret.Source, ret.Defines, width, height, depth, channelCount, db); Logger.Log(DebugChannel.Log | DebugChannel.OpenFL, Verbosity.Level5, "Parsing Script Defines for File: " + file); ParseDefines(instance, SCRIPT_DEFINE_KEY, DefineScript, ret.Source, ret.Defines, width, height, depth, channelCount, db); Logger.Log(DebugChannel.Log | DebugChannel.OpenFL, Verbosity.Level5, "Parsing JumpLocations for File: " + file); ret.JumpLocations = ParseJumpLocations(ret.Source); Logger.Log(DebugChannel.Log | DebugChannel.OpenFL, Verbosity.Level5, "Parsing Instruction Data for File: " + file); foreach (string line in ret.Source) { Logger.Log(DebugChannel.Log | DebugChannel.OpenFL, Verbosity.Level3, "Parsing Instruction Data for Line: " + line); FLInstructionData data = GetInstructionData(line, ret.Defines, ret.JumpLocations, funcs, db); Logger.Log(DebugChannel.Log | DebugChannel.OpenFL, Verbosity.Level3, "Parsed Instruction Data: " + Enum.GetName(typeof(FLInstructionType), data.InstructionType)); ret.ParsedSource.Add(data); } return(ret); }
/// <summary> /// Executes one step of the Processor /// </summary> private void Execute() { FLInstructionData data = Data.ParsedSource[_currentIndex]; if (data.InstructionType == FLInstructionType.NOP || data.InstructionType == FLInstructionType.Unknown) { _currentIndex++; _currentWord = 0; } else { LineAnalysisResult ret = AnalyzeLine(data); if (ret != LineAnalysisResult.Jump) { _currentIndex++; _currentWord = 0; } } DetectEnd(); }
private FLInstructionData GetInstructionData(string line, Dictionary <string, CLBufferInfo> defines, Dictionary <string, int> jumpLocations, Dictionary <string, FLInterpreterFunctionInfo> funcs, KernelDatabase db) { string[] code = SplitLine(SanitizeLine(line)); if (code.Length == 0) { return(new FLInstructionData { InstructionType = FLInstructionType.Nop }); } if (code[0].Trim().EndsWith(FUNCTION_NAME_POSTFIX)) { return(new FLInstructionData { InstructionType = FLInstructionType.FunctionHeader }); } bool isBakedFunction = funcs.ContainsKey(code[0]); FLInstructionData ret = new FLInstructionData(); if (isBakedFunction) { ret.InstructionType = FLInstructionType.FlFunction; ret.Instruction = funcs[code[0]]; } else if (db.TryGetClKernel(code[0], out CLKernel kernel)) { ret.Instruction = kernel; ret.InstructionType = FLInstructionType.ClKernel; } List <FLArgumentData> argData = new List <FLArgumentData>(); for (int i = 1; i < code.Length; i++) { if (defines.ContainsKey(code[i])) { argData.Add(new FLArgumentData { value = defines[code[i]], argType = FLArgumentType.Buffer }); } else if (jumpLocations.ContainsKey(code[i])) { argData.Add( new FLArgumentData { value = jumpLocations[code[i]], argType = FLArgumentType.Function }); } else if (decimal.TryParse(code[i], NumberStyles.Any, NumberParsingHelper, out decimal valResult)) { argData.Add(new FLArgumentData { value = valResult, argType = FLArgumentType.Number }); } else { argData.Add(new FLArgumentData { value = null, argType = FLArgumentType.Unknown }); throw new FLInvalidArgumentType(code[i], "Number or Defined buffer."); } } ret.Arguments = argData; return(ret); }
private FLLineAnalysisResult AnalyzeLine(FLInstructionData data) { if (data.InstructionType != FLInstructionType.FlFunction && data.InstructionType != FLInstructionType.ClKernel) { return(FLLineAnalysisResult.ParseError); } if (leaveStack) //This keeps the stack when returning from a "function" { leaveStack = false; } else { currentArgStack = new Stack <object>(); } FLLineAnalysisResult ret = FLLineAnalysisResult.IncreasePc; for (; currentWord < data.Arguments.Count; currentWord++) //loop through the words. start value can be != 0 when returning from a function specified as an argument to a kernel { if (data.Arguments[currentWord].argType == FLArgumentType.Function) { bool keepBuffer = data.InstructionType == FLInstructionType.FlFunction && ((FLInterpreterFunctionInfo)data.Instruction).LeaveStack; JumpTo((int)data.Arguments[currentWord].value, keepBuffer); ret = FLLineAnalysisResult.Jump; //We Jumped to another point in the code. currentArgStack .Push(null); //Push null to signal the interpreter that he returned before assigning the right value. break; } if (data.Arguments[currentWord].argType != FLArgumentType.Unknown) { currentArgStack.Push(data.Arguments[currentWord].value); } } if (currentWord == data.Arguments.Count && ret != FLLineAnalysisResult.Jump) { if (data.InstructionType == FLInstructionType.FlFunction) { ((FLInterpreterFunctionInfo)data.Instruction).Run(); return(FLLineAnalysisResult.IncreasePc); } CLKernel k = (CLKernel)data.Instruction; if (k == null || data.Arguments.Count != k.Parameter.Count - FL_HEADER_ARG_COUNT) { throw new FLInvalidFunctionUseException(this.data.Source[currentIndex], "Not the right amount of arguments."); } //Execute filter for (int i = k.Parameter.Count - 1; i >= FL_HEADER_ARG_COUNT; i--) { object obj = currentArgStack.Pop(); //Get the arguments and set them to the kernel if (obj is CLBufferInfo buf) //Unpack the Buffer from the CLBuffer Object. { obj = buf.Buffer; } k.SetArg(i, obj); } Logger.Log(DebugChannel.Log | DebugChannel.OpenFL, Verbosity.Level8, "Running kernel: " + k.Name); CLAPI.Run(instance, k, currentBuffer.Buffer, new int3(width, height, depth), KernelParameter.GetDataMaxSize(kernelDb.GenDataType), activeChannelBuffer, channelCount); //Running the kernel } return(ret); }
private LineAnalysisResult AnalyzeLine(FLInstructionData data) { if (data.InstructionType != FLInstructionType.FLFunction && data.InstructionType != FLInstructionType.CLKernel) { Logger.Crash(new FLParseError(Data.Source[_currentIndex]), true); return(LineAnalysisResult.ParseError); } if (_leaveStack) //This keeps the stack when returning from a "function" { _leaveStack = false; } else { _currentArgStack = new Stack <object>(); } LineAnalysisResult ret = LineAnalysisResult.IncreasePC; for (; _currentWord < data.Arguments.Count; _currentWord++) //loop through the words. start value can be != 0 when returning from a function specified as an argument to a kernel { if (data.Arguments[_currentWord].argType == FLArgumentType.Function) { bool KeepBuffer = data.InstructionType == FLInstructionType.FLFunction && ((FLFunctionInfo)data.Instruction).LeaveStack; JumpTo((int)data.Arguments[_currentWord].value, KeepBuffer); ret = LineAnalysisResult.Jump; //We Jumped to another point in the code. _currentArgStack .Push(null); //Push null to signal the interpreter that he returned before assigning the right value. break; } if (data.Arguments[_currentWord].argType != FLArgumentType.Unknown) { _currentArgStack.Push(data.Arguments[_currentWord].value); } } if (_currentWord == data.Arguments.Count && ret != LineAnalysisResult.Jump) { if (data.InstructionType == FLInstructionType.FLFunction) { ((FLFunctionInfo)data.Instruction).Run(); return(LineAnalysisResult.IncreasePC); } CLKernel K = (CLKernel)data.Instruction; if (K == null || data.Arguments.Count != K.Parameter.Count - FLHeaderArgCount) { Logger.Crash(new FLInvalidFunctionUseException(Data.Source[_currentIndex], "Not the right amount of arguments."), true); return(LineAnalysisResult.ParseError); } //Execute filter for (int i = K.Parameter.Count - 1; i >= FLHeaderArgCount; i--) { object obj = _currentArgStack.Pop(); //Get the arguments and set them to the kernel if (obj is CLBufferInfo buf) //Unpack the Buffer from the CLBuffer Object. { obj = buf.Buffer; } K.SetArg(i, obj); } Logger.Log("Running kernel: " + K.Name, DebugChannel.Log | DebugChannel.OpenFL, 8); CLAPI.Run(K, _currentBuffer.Buffer, new int3(_width, _height, _depth), KernelParameter.GetDataMaxSize(_kernelDb.GenDataType), _activeChannelBuffer, _channelCount); //Running the kernel } return(ret); }