Code archives/Miscellaneous/Use blitzcc.exe to run BlitzPlus/3D code in your BlitzPlus/3D Program
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
FREE AS IN BEER AND SPEECH Disclaimer: This comes as is. It was tested in BlitzPlus 1.47. It also requires blitzcc.exe in %BLITZPATH%\bin. I know it can be optimized further. I know it lacks error checking. I was excited at my progress so I decided to post this here. Take it, have fun with it. I'm not sure if it's even legit to do something like this, but TADA! NOTE: You can run multiple lines of code by separating them with colons (which is, of course, a feature of BlitzPlus/3D) (don't quote me on the 3D) | |||||
; Loopback Interpreter Script server/client ; INITILIALIZATION ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; DebugLog "Initializing BlitzPlus Interpreter v"+VERSION ; Set up a BLITZPATH variable in the environment, if it isn't already there (necessary to run blitzcc.exe) If GetEnv("BLITZPATH") = "" Then SetEnv "BLITZPATH", GetEnv("ProgramFiles")+"\BlitzPlus" DebugLog "BLITZPATH="+GetEnv("BLITZPATH") ; it isn't really necessary, but making this global up here saves room in the function below (bps=BlitzPlus script) Global runbps$ = "cmd /C "+Chr(34)+GetEnv("BLITZPATH")+"\bin\blitzcc.exe"+Chr(34)+" cmd.bps >output.txt" ; get a server up to accept your input and "interpret" it Global server = CreateTCPServer(9876) ; open a stream on the loopback address to send commands through Global typer = OpenTCPStream("127.0.0.1", 9876) ; accept the stream above as the interpreter's I/O Global interpreter = AcceptTCPStream(server) DebugLog "runbps = " + runbps DebugLog "server = " + server DebugLog "typer = " + typer DebugLog "interpreter = " + interpreter DebugLog "Initialization Complete. Awaiting command." Print "BlitzPlus Interpreter v0.0.1" ; GAME/PROGRAM LOOP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; This loop here uses the Input function to take commands from the user. This is not a limitation, ; but a demo of how it could be used. Basically to send something to the interpreter Write[String, ; Byte, Line, etc] it to the typer stream. While resp$ <> "exit" ; Once again, the Input part is just for demo, you can generate your cmd anyway you can think of cmd$ = Input(">>> ") ; get the right-before-send time start=MilliSecs() ; Take the input and throw it on the input stream WriteString typer, cmd ; Run all the data on the interpreter stream While ReadAvail(interpreter) RunScript() Wend ; print the results to screen, as they are grabbed form the typer buffer While ReadAvail(typer) resp$ = ReadString(typer) If resp = "exit" Then Exit Else Print resp Wend ; Logs the time from enter-key to the next prompt/exit DebugLog(Str(MilliSecs()-start)+"ms roundtrip") Wend ; Close the input, and kill the server (kills the output stream) CloseTCPStream in CloseTCPServer server Function RunScript() ; Take the cmd as a string off the stream cmd$ = ReadString(interpreter) DebugLog "Input: " + cmd ; For convenience in this interactive version, I added this exit functionality. If Lower(cmd) = "exit" Then DebugLog "Exiting" WriteString interpreter, "exit" Return EndIf ; Type a bang (!) to stop the interpreter in debug mode. VERY USEFUL If cmd = "!" Then Stop ; Blank lines get ignored, otherwise try doing the cmd ElseIf cmd <> "" Then ; Open a file to write our command to. (blitzcc.exe accepts files) DebugLog "Opening ./cmd.bps for writing" Local outfile = WriteFile("./cmd.bps") DebugLog "outfile = " + outfile ; About the only ounce of error-checking with I bothered with for now If Not outfile Then DebugLog "Unable to open cmd.bps for writing" RuntimeError "Unable to open cmd.bps for writing" EndIf ; Write our cmd to the file DebugLog "Writing to cmd.bps" WriteLine outfile, cmd ; Close the file... we can't go sending open files around. DebugLog "Closing cmd.bps" CloseFile outfile ; Delete old output -- artifact of when I had some latency issues before. ; Better safe than sorry DebugLog "Checking for (and deleting) old output" If FileType("./output.txt") = 1 Then DeleteFile "./output.txt" ; Run blitzcc on the cmd file DebugLog "Calling blitzcc to run cmd.bps" ExecFile(runbps$) ; Look for the file--not there? KEEP LOOKING! While Not FileType("./output.txt") DebugLog "No output file yet" Delay 17 Wend ; We need to wait until the file is not being written to, so we get the whole output. ; I couldn't think of anything better yet. DebugLog "Waiting for file size to stop changing" Local newsize = FileSize("./output.txt") Local oldsize = -1 While oldsize <> newsize oldsize = newsize newsize = FileSize("./output.txt") ; The reason it takes half a second to do a print :( ; You might be able to shorten the delays depending on the machine running this. Delay 365 Wend ; Part of our command was to pipe output into a file, so now we read it Local ostream = ReadFile("./output.txt") DebugLog "ostream = " + ostream + " Available: " + FileSize(ostream) ; There's a mess of stuff that prints out when you run blitzcc at the command line ; The loop goes through the file and when something unusual comes up (errors, your output) ; it writes it to the stream so we can get it in a minute Local expected$ = "BlitzCC" While Not Eof(ostream) Local outline$ = ReadLine(ostream) DebugLog "Output: " + outline If (Len(expected) <> 0) And (expected = Left(outline, Len(expected))) Then ; A mutually exclusive list of expected values that gets the interpreter through the header If expected = "Executing..." Then expected = "" If expected = "Assembling..." Then expected = "Executing..." If expected = "Translating..." Then expected = "Assembling..." If expected = "Generating..." Then expected = "Translating..." If expected = "Parsing..." Then expected = "Generating..." If expected = "Compiling" Then expected = "Parsing..." If expected = "(C)" Then expected = "Compiling" If expected = "BlitzCC" Then expected = "(C)" Else ; This is where the output, good or bad, gets sent back WriteString interpreter, outline EndIf Wend EndIf ; Close and delete the output file -- under redundant, see redundant :) DebugLog "Closing ostream" CloseFile ostream DebugLog "Deleting output.txt" DeleteFile "./output.txt" End Function |
Comments
| ||
Awesome!!! To help people out at how this works, at least for blitz3D, type something like ' Print "Hello World!" : Waitkey() ' then hit Enter, might have to hit enter a second time. Very useful epiblitikos! |
Code Archives Forum