Code: Select all
/*
Requires TCC: https://download.savannah.gnu.org/releases/tinycc/tcc-0.9.27-win64-bin.zip
Place script in TCC folder or locate it when prompted.
*/
#singleinstance force
path := A_ScriptDir
;----------------------------
;define a C function string
stringC1 := new tcc('
(
char* hello() {
return "hello world";
}
)', path)
msgbox(DllCall(stringC1["hello"], "AStr"))
haystack := "The quick brown fox jumps over the lazy dog."
needle := "fly"
tcc.__StrPutVar(haystack, _haystack)
tcc.__StrPutVar(needle, _needle)
stringC2 := new tcc('
(
#include <string.h>
int match(char *haystack, char *needle) {
int r = strpbrk(haystack, needle)-haystack+1;
return r > 0 ? r : 0;
}
)', path)
msgbox( 'Found a char from: "' needle '" in "' haystack '" at position: '
. DllCall( stringC2["match"], "Str", _haystack, "Str", _needle ) )
;---------------------------
;define a C comment block
commentC := new tcc(parseC())
/*_C
#include <math.h>
int inc() {
static int i = 0;
return ++i;
}
int sqrt3(double *d) {
*d = sqrt(3);
}
*/
DllCall(commentC["sqrt3"], "Ptr", &_sqrt := 0.0)
msgbox("sqrt(3) = " _sqrt)
;save function pointer to variable for speed
f := commentC["inc"]
t := A_TickCount
loop 1000000
x := DllCall(f)
msgbox("x = " x " (Time elapsed: " A_TickCount - t " ms)" )
;===============================================================================================================
parseC(path:="") {
path := path ? path : A_ScriptFullPath
;read c code
,startLabel := "`n/*_" "C"
,endLabel := "`n*/"
,script := fileRead(A_ScriptFullPath)
,cStart := InStr(script, startLabel) + StrLen(startLabel) + 2
,cEnd := InStr(script, endLabel, , cStart + 1)
,_cStr := SubStr(script, cStart, cEnd - cStart)
loop parse _cStr "`n", "`r"
cStr .= (A_LoopField ~= "^[\s]+;") ? "" : A_LoopField ;ignore lines starting with ; (AHK escape)
return cStr
}
class tcc {
__New(cStr, tccPath := "") {
static _path := ""
tccPath := _path ? _path : tccPath
while !FileExist(tccPath "\libtcc.dll")
_path := tccPath := DirSelect(, , "Locate TCC folder")
cStr := (InStr(cStr, "main(") ? "" : "int main() {return 0;}`n") cStr
,tccPath := tccPath ? tccPath : A_ScriptDir
,hModule := DllCall("LoadLibrary", "Str", tccPath "\libtcc.dll", "Ptr")
,Context := DllCall("libtcc\tcc_new", "Ptr")
,this.__StrPutVar(tccPath "\lib", libraryPath)
,this.__StrPutVar(tccPath "\include", includePath)
,this.__StrPutVar(tccPath "\include", sysincludePath)
,this.__StrPutVar(tccPath, tcclibPath)
,DllCall("libtcc\tcc_add_library_path", "Ptr", context, "Str", libraryPath, "Int")
,DllCall("libtcc\tcc_add_include_path", "Ptr", context, "Str", includePath, "Int")
,DllCall("libtcc\tcc_add_sysinclude_path", "Ptr", context, "Str", sysincludePath, "Int")
,DllCall("libtcc\tcc_set_lib_path", "Ptr", context, "Str", tcclibPath)
;~ ,this.StrPutVar("-luser32 -lkernel32", options)
;~ ,DllCall("libtcc\tcc_set_options", "Ptr", context, "Str", options)
,DllCall("libtcc\tcc_set_output_type", "Ptr", context, "UInt", TCC_OUTPUT_MEMORY := 1, "Int")
,this.__StrPutVar(cStr, _cStr)
,DllCall("libtcc\tcc_compile_string", "Ptr", context, "Str", _cStr, "Int")
;,DllCall("libtcc\tcc_run", "Ptr", context)
,DllCall("libtcc\tcc_relocate", "Ptr", context, "Ptr", TCC_RELOCATE_AUTO := 1, "Int")
,this.context := context, this.hModule := hModule, this.symbols := {}
}
__Get(fStr) {
return (
this.symbols[fStr] ?(
this.symbols[fStr]
):(
this.__StrPutVar(fStr, _fStr)
,this.symbols[fStr] := DllCall("libtcc\tcc_get_symbol", "Ptr", this.context, "Str", _fStr, "Ptr")
)
)
}
__Delete() {
DllCall("libtcc\tcc_delete", "Ptr", this.context)
,DllCall("FreeLibrary", "Ptr", this.hModule)
}
__StrPutVar(string, ByRef var, encoding := "cp0") {
return (
VarSetCapacity(var, StrPut(string, encoding) * ((encoding="utf-16"||encoding="cp1200") ? 2 : 1) )
,StrPut(string, &var, encoding)
)
}
}