Compare commits

..

424 Commits

Author SHA1 Message Date
xushiwei
75ca4af74e Merge pull request #442 from xushiwei/q
README: chan
2024-07-02 21:05:04 +08:00
xushiwei
dc5fc6bdc2 README: chan 2024-07-02 21:04:34 +08:00
xushiwei
67f8ee61a4 Merge pull request #440 from visualfc/chan
ssa: chan send/recv
2024-07-02 21:00:09 +08:00
visualfc
2153cf39b5 ssa: chan send/recv 2024-07-02 20:52:25 +08:00
xushiwei
0ead82ae21 Merge pull request #441 from xushiwei/q
runtime: close(chan)
2024-07-02 20:27:11 +08:00
xushiwei
98d4cf7585 runtime: close(chan) 2024-07-02 20:23:48 +08:00
xushiwei
3259536411 Merge pull request #439 from xushiwei/q
demo: cchan
2024-07-02 19:49:21 +08:00
xushiwei
f3a79cc779 demo: cchan 2024-07-02 19:49:00 +08:00
xushiwei
c45c6dbe67 Merge pull request #436 from luoliwoshang/link/warning
link:not exist method warning
2024-07-02 19:43:37 +08:00
xushiwei
a1518c33af Merge pull request #438 from visualfc/build_link
build: fix link runtime
2024-07-02 19:43:11 +08:00
visualfc
a9f7cdb630 build: fix link runtime 2024-07-02 18:40:20 +08:00
luoliwoshang
6f678294a0 link:not exist method warning 2024-07-02 17:37:32 +08:00
xushiwei
de07abee98 Merge pull request #437 from xushiwei/q
runtime: chan; cmptest: iodemo, fmtdemo
2024-07-02 16:05:14 +08:00
xushiwei
437edefa0c runtime: chan 2024-07-02 16:00:43 +08:00
xushiwei
f5b36ecbac Merge pull request #434 from visualfc/abi_patch
ssa: fix abi patch types.pointer
2024-07-02 12:14:54 +08:00
visualfc
8772c85964 ssa: fix abi patch types.pointer 2024-07-02 08:40:44 +08:00
xushiwei
a31454327a Update README.md 2024-07-02 07:39:53 +08:00
xushiwei
9e55cb114c Merge pull request #433 from xushiwei/q
abitype: support Patch (Clone + Merge); patch: os.File
2024-07-01 19:09:32 +08:00
xushiwei
04416a67d3 cl: SetPatch fix 2024-07-01 19:05:12 +08:00
xushiwei
dd2cdaf49a Merge pull request #425 from visualfc/makeslice
ssa: makeSlice fit int size and check
2024-07-01 16:59:27 +08:00
xushiwei
8c45eb7524 abitype: support Patch 2024-06-30 11:53:12 +08:00
xushiwei
c20bea50e3 Merge remote-tracking branch 'gop/main' into q 2024-06-30 11:16:53 +08:00
xushiwei
fe18c35dab patch: Clone/Merge 2024-06-28 15:14:30 +08:00
xushiwei
f6ef6abdf1 Merge pull request #424 from aofei/llvm
xtool: utilize llvm-config to find LLVM executables
2024-06-28 13:17:09 +08:00
Aofei Sheng
43a6837e81 xtool: utilize llvm-config to find LLVM executables 2024-06-27 20:27:42 +08:00
visualfc
dc4b933000 ssa: makeSlice both len/cap be non-nil 2024-06-27 20:01:27 +08:00
visualfc
c90703dc13 ssa: makeSlice fit int size and check 2024-06-27 19:57:44 +08:00
xushiwei
2165941026 patch: os.File 2024-06-27 02:28:18 +08:00
xushiwei
4a28893171 Merge pull request #429 from xushiwei/q
patch: fmt, os, runtime, syscall, time
2024-06-27 01:05:13 +08:00
xushiwei
369581976a c/time fix 2024-06-27 01:00:58 +08:00
xushiwei
7fef683980 c.Long as int64 2024-06-27 00:55:33 +08:00
xushiwei
8358f68086 Merge pull request #428 from visualfc/bytealg
ssa fix slice high, update bytealg for pkg bytes/strings
2024-06-27 00:53:42 +08:00
xushiwei
0aa6b03c2a patch time: Now 2024-06-27 00:51:21 +08:00
xushiwei
44f8c98660 demo: c ClockGettime (CLOCK_REALTIME/MONOTONIC) 2024-06-26 21:20:47 +08:00
xushiwei
188ec6ea1d patch time: time.Format 2024-06-26 20:41:34 +08:00
visualfc
8169d8509f cl/_testlibgo: bytes strings 2024-06-26 20:41:29 +08:00
visualfc
e217d39882 internal/lib/internal/bytealg: count index 2024-06-26 20:13:43 +08:00
visualfc
887ee0fd41 ssa: fix slice high 2024-06-26 20:09:38 +08:00
xushiwei
137e93319e c/time; patch: time 2024-06-26 19:36:39 +08:00
xushiwei
48a1384197 patch: fmt, os, runtime, syscall, time 2024-06-26 17:17:10 +08:00
xushiwei
8aed4d634b Merge pull request #427 from xushiwei/q
raylib demo: tetris
2024-06-26 00:52:16 +08:00
xushiwei
fd0cb4c458 raylib demo: tetris 2024-06-26 00:49:20 +08:00
xushiwei
82735f0fab Merge pull request #426 from xushiwei/q
patch os: File.Write
2024-06-26 00:31:33 +08:00
xushiwei
1d3710afd8 toSyscallErr => syscall.Errno 2024-06-26 00:28:21 +08:00
xushiwei
e8ae92f4d4 Merge pull request #423 from luoliwoshang/raylibdemo
llgo/c/raylib:tetris demo
2024-06-26 00:03:51 +08:00
luoliwoshang
b2e54a0590 llgo/c/raylib:tetris demo 2024-06-25 20:54:07 +08:00
xushiwei
d64d220b49 patch os: File.Write 2024-06-25 18:07:58 +08:00
xushiwei
2523a95a9a Merge pull request #422 from xushiwei/q
patch os, syscall, io/fs: Errno, Stdin/out/err
2024-06-25 16:14:25 +08:00
xushiwei
207c41581c patch syscall: errors for linux 2024-06-25 16:11:29 +08:00
xushiwei
6fc4a3ed04 patch os, syscall, io/fs: Errno, Stdin/out/err 2024-06-25 16:02:54 +08:00
xushiwei
2fabb6951e Merge pull request #421 from visualfc/abibasic
runtime: global abi basic
2024-06-25 15:46:00 +08:00
xushiwei
8c2f5f91d5 Merge pull request #420 from xushiwei/q
patch os: UserHomeDir/UserConfigDir/UserCacheDir
2024-06-25 15:45:29 +08:00
visualfc
7443d41444 runtime: global abi basic 2024-06-25 14:41:32 +08:00
xushiwei
4421734da1 patch os: UserHomeDir/UserConfigDir/UserCacheDir 2024-06-25 14:29:37 +08:00
xushiwei
4385ca0966 patch: internal/abi 2024-06-25 14:02:25 +08:00
xushiwei
57fa592a13 Merge pull request #419 from xushiwei/q
phi.AddIncoming fix: use checkExpr
2024-06-25 13:35:42 +08:00
xushiwei
1298118b59 phi.AddIncoming fix: use checkExpr 2024-06-25 13:31:44 +08:00
xushiwei
3f2cb40cc1 Merge pull request #418 from xushiwei/q
cmptest: sortdemo
2024-06-25 12:40:55 +08:00
xushiwei
5448abb304 cmptest: sortdemo 2024-06-25 12:40:28 +08:00
xushiwei
892fab5455 Merge pull request #417 from visualfc/abinamed
ssa: fix abiType & abiNamedOf
2024-06-25 12:34:23 +08:00
visualfc
ef3619350d ssa: fix abiType & abiNamedOf 2024-06-25 12:17:03 +08:00
xushiwei
846fb3e7f3 Merge pull request #416 from xushiwei/q
c/clang: use llvm-config
2024-06-25 12:05:05 +08:00
xushiwei
e00e9ba5aa c/clang: use llvm-config 2024-06-25 12:00:48 +08:00
xushiwei
f41511047e Merge pull request #392 from visualfc/rlite
ssa: fix abiType && abiMethoOf
2024-06-25 10:45:00 +08:00
visualfc
16352df5b1 ssa: fix abiType && abiMethoOf 2024-06-25 10:22:32 +08:00
xushiwei
5238c2457d Merge pull request #415 from xushiwei/q
c/raylib
2024-06-25 08:42:57 +08:00
xushiwei
4d57f414f5 c/raylib 2024-06-25 08:40:23 +08:00
xushiwei
6305088cb0 Merge pull request #414 from xushiwei/q
c/math (float32); c/math/rand
2024-06-25 01:32:58 +08:00
xushiwei
e2db1cd425 c/math (float32); c/math/rand 2024-06-25 01:30:13 +08:00
xushiwei
16561a8e84 Merge pull request #413 from xushiwei/q
c/zlib: Z_OK => OK
2024-06-25 01:24:42 +08:00
xushiwei
cae1b3ebd4 c/zlib: Z_OK => OK 2024-06-25 01:02:03 +08:00
xushiwei
e68737dcfb Merge pull request #404 from luoliwoshang/zlib
llgo/c/zlib
2024-06-25 00:45:19 +08:00
xushiwei
00448d23c0 Merge pull request #408 from aofei/llama2-libm
fix(c/llama2): explicitly link libm to ensure compatibility with Linux
2024-06-25 00:43:28 +08:00
xushiwei
272ae547ef Merge pull request #410 from xushiwei/q
c/clang; c/raylib demo
2024-06-25 00:43:07 +08:00
xushiwei
3fd688191c c/clang 2024-06-25 00:33:48 +08:00
luoliwoshang
5c0b6f2225 llgo/c/zlib 2024-06-24 23:03:18 +08:00
xushiwei
cc530e3446 c/raylib demo 2024-06-24 22:37:53 +08:00
xushiwei
fdc1d46b89 Merge pull request #409 from xushiwei/q
c/raylib
2024-06-24 22:03:54 +08:00
xushiwei
5dce677091 c/raylib 2024-06-24 21:56:53 +08:00
Aofei Sheng
d0fb5a4b04 fix(c/llama2): explicitly link libm to ensure compatibility with Linux 2024-06-24 17:50:05 +08:00
xushiwei
e27daed0ec c/llama2: rm precompiled *.ll files (#407) 2024-06-24 17:31:59 +08:00
xushiwei
d2183a8b32 c/llama2: rm precompiled *.ll files 2024-06-24 17:27:12 +08:00
七叶
0b2d6407dd runtime: type align (#405) 2024-06-24 17:15:45 +08:00
tsingbx
ec1b1ffe16 add math/rand (#403)
c/math/rand
2024-06-24 15:53:26 +08:00
xushiwei
32a66be555 Merge pull request #399 from visualfc/panicany
runtime: panic any custometype
2024-06-23 23:01:17 +08:00
visualfc
c090c34491 runtime: panic any custometype 2024-06-23 21:51:00 +08:00
xushiwei
4f7d3ad76c Merge pull request #398 from xushiwei/q
cppmintf: implements multiple intefaces in c++
2024-06-23 16:19:52 +08:00
xushiwei
ce81872686 cppintf: fix int type 2024-06-23 16:14:42 +08:00
xushiwei
2314c41103 cppmintf: implements multiple intefaces in c++ 2024-06-23 16:12:01 +08:00
xushiwei
df39b66e11 Merge pull request #394 from xushiwei/q
mv cases to _cmptest
2024-06-23 01:00:28 +08:00
xushiwei
adeb5de19f mv cases to _cmptest 2024-06-23 01:00:02 +08:00
xushiwei
26312e0c0e Merge pull request #393 from xushiwei/q
llgo cmptest (#391)
2024-06-23 00:53:41 +08:00
xushiwei
cd6d4021b1 llgo cmptest (#391) 2024-06-23 00:48:38 +08:00
xushiwei
24d345a970 Merge pull request #389 from xushiwei/q
cppintf: c++ name
2024-06-22 09:15:08 +08:00
xushiwei
b4fd4a0c38 cppintf: c++ name 2024-06-22 09:14:10 +08:00
xushiwei
451e695006 Merge pull request #388 from xushiwei/q
cppintf: with param
2024-06-22 08:42:35 +08:00
xushiwei
26b771f9f9 cppintf: with param 2024-06-22 02:39:29 +08:00
xushiwei
0679aedb7e Merge pull request #387 from xushiwei/q
cl: c.Func (llgo.funcAddr); demo: cppintf (how to use c++ interface)
2024-06-21 23:50:13 +08:00
xushiwei
bfa4e08a4e cl: c.Func (llgo.funcAddr); demo: cppintf (how to use c++ interface) 2024-06-21 23:44:56 +08:00
xushiwei
c1185a34aa Merge pull request #386 from xushiwei/q
build: disable verbose info for deps
2024-06-21 15:47:52 +08:00
xushiwei
be0ce57375 build: disable debug info for deps 2024-06-21 15:45:29 +08:00
xushiwei
b204b90ffc build: remove context.verbose 2024-06-21 15:31:18 +08:00
xushiwei
364b6938a5 Merge pull request #385 from xushiwei/q
patch: internal/reflectlite; demo: sort
2024-06-21 13:47:16 +08:00
xushiwei
e188925d2b patch: internal/reflectlite; demo: sort 2024-06-21 13:21:16 +08:00
xushiwei
10a47cdbbb build: use unsafe.Slice to reduce memory usage of overlayFiles 2024-06-21 12:43:17 +08:00
xushiwei
67014ae4f8 Merge pull request #384 from xushiwei/q
patch internal/reflectlite; demo: sort.Ints
2024-06-21 11:23:13 +08:00
xushiwei
b93fc3f028 patch internal/reflectlite; demo: sort.Ints 2024-06-21 11:02:28 +08:00
xushiwei
b6e5980510 Merge pull request #383 from visualfc/skipfiles
x/build: overlayFiles for fix math on amd64
2024-06-21 10:46:38 +08:00
visualfc
79e8921f76 x/build: overlayFiles for fix math on amd64 2024-06-21 07:55:17 +08:00
xushiwei
34fe3ca4fc Merge pull request #382 from xushiwei/q
patch reflect: Append/Index; Int fix
2024-06-21 03:33:44 +08:00
xushiwei
f26311c60e patch reflect: Append/Index; Int fix 2024-06-21 03:29:24 +08:00
xushiwei
43f9907af7 Merge pull request #381 from xushiwei/q
patch reflect: ValueOf/Int
2024-06-21 00:42:12 +08:00
xushiwei
0e6f5d154e patch reflect: ValueOf/Int 2024-06-21 00:31:36 +08:00
xushiwei
7042dd8447 Merge pull request #380 from xushiwei/q
patch reflect: Zero/Len
2024-06-20 23:44:51 +08:00
xushiwei
05031e0979 patch reflect: Zero/Len 2024-06-20 23:40:35 +08:00
xushiwei
28b3f6780c Merge pull request #379 from xushiwei/ll
README: reflect (partially)
2024-06-20 22:30:44 +08:00
xushiwei
f8335c6df9 README: reflect (partially) 2024-06-20 22:24:03 +08:00
xushiwei
9dcdc1f8f3 Merge pull request #378 from visualfc/abikind
ssa: abiTypeInit kind
2024-06-20 22:22:47 +08:00
visualfc
9ae7d4f2bf ssa: abiTypeInit kind 2024-06-20 22:09:26 +08:00
xushiwei
c158169bdf Merge pull request #373 from visualfc/complex
ssa: complex op and print/panic
2024-06-20 22:05:04 +08:00
visualfc
e4c1285eaf ssa: complex binop 2024-06-20 20:44:07 +08:00
visualfc
02a5375503 runtime: print/panic complex 2024-06-20 20:44:07 +08:00
xushiwei
32883b4e18 Merge pull request #377 from cpunion/fix-abi-init
Fix reentrant of ABI initialization
2024-06-20 20:36:41 +08:00
Li Jie
6d585e88a4 cl: output export file path of package in verbose 2024-06-20 20:13:53 +08:00
Li Jie
73570b5628 cl: re-generate tests 2024-06-20 20:13:53 +08:00
Li Jie
e7fcb068d9 ssa: fix reentrant of ABI initialization 2024-06-20 20:07:59 +08:00
xushiwei
a137a70278 Merge pull request #376 from xushiwei/ll
README: os (partially)
2024-06-20 19:56:40 +08:00
xushiwei
72113991a8 README: os (partially) 2024-06-20 19:55:37 +08:00
xushiwei
a04fb8e7de Merge pull request #371 from xushiwei/q
patch: reflect (reflect.Type)
2024-06-20 17:51:31 +08:00
xushiwei
ca2f30cd61 Merge pull request #375 from aofei/build-gopath
build: remove check for default GOPATH and GOROOT being identical
2024-06-20 17:47:44 +08:00
Aofei Sheng
ebfad05e3f build: remove check for default GOPATH and GOROOT being identical 2024-06-20 17:42:01 +08:00
xushiwei
f54ea9d978 Merge pull request #374 from xushiwei/check
complex testcase
2024-06-20 16:07:14 +08:00
xushiwei
d4c84cee19 complex demo 2024-06-20 16:00:11 +08:00
xushiwei
4da59cdc97 Merge pull request #363 from visualfc/panic
runtime: tracePanic
2024-06-20 15:42:51 +08:00
xushiwei
d4e7eb5888 bytealg.IndexByteString 2024-06-20 14:31:05 +08:00
xushiwei
f8b0a7105b patch: reflect (type) 2024-06-20 14:17:37 +08:00
visualfc
aecde91d33 runtime: tracePanic 2024-06-20 13:05:43 +08:00
xushiwei
870dde232a Merge pull request #369 from xushiwei/q
library: strconv
2024-06-20 11:09:43 +08:00
xushiwei
f7d7f81c49 library: strconv 2024-06-20 11:05:43 +08:00
xushiwei
1f04c61482 Merge pull request #368 from xushiwei/q
builtin: real/imag/complex; c/math/cmplx; patch: math/cmplx
2024-06-20 10:31:24 +08:00
xushiwei
5d957a6b7c libc complex64 support 2024-06-20 10:22:35 +08:00
xushiwei
94f61b0a0c TestFromTestlibgo 2024-06-20 10:07:10 +08:00
xushiwei
de6535b722 builtin: real/imag/complex; c/math/cmplx; patch: math/cmplx 2024-06-20 10:00:47 +08:00
xushiwei
6dd18e4328 Merge pull request #362 from aofei/build
build: set $GOPATH/bin as default GOBIN for Config.BinPath
2024-06-20 08:20:21 +08:00
Aofei Sheng
c46e4453c7 build: set $GOPATH/bin as default GOBIN for Config.BinPath
We should avoid making any changes to GOROOT whenever possible.

Fixes #361

Update internal/build/build.go

Co-authored-by: 张之阳 <51194195+luoliwoshang@users.noreply.github.com>
2024-06-20 08:14:05 +08:00
xushiwei
2e6312ec03 Merge pull request #366 from xushiwei/q
patch: syscall
2024-06-20 03:05:20 +08:00
xushiwei
1566a834e1 x 2024-06-20 03:00:12 +08:00
xushiwei
607deaa3c4 patch: syscall 2024-06-20 02:55:26 +08:00
xushiwei
686186d5ba Merge pull request #365 from xushiwei/q
cjson/sqlite README: remove install from source
2024-06-20 00:47:37 +08:00
xushiwei
0c1ef72285 cjson/sqlite README: remove install from source 2024-06-20 00:44:15 +08:00
xushiwei
d6bd12cfcd Merge pull request #364 from xushiwei/q
patch: io, io/fs, os; llgo.string; c string library; demo: getcwd; abi.TypeName fix: error interface is public
2024-06-20 00:35:10 +08:00
xushiwei
4a1712f4cd llgo.string (llgo/ssa.MakeString) fix 2024-06-20 00:30:36 +08:00
xushiwei
b4e298230d x 2024-06-20 00:13:41 +08:00
xushiwei
6cb42a4251 demo: getcwd; abi.TypeName fix: error interface is public 2024-06-19 23:58:20 +08:00
xushiwei
3ead4b4d4b llgo.string; c string library 2024-06-19 23:40:05 +08:00
xushiwei
3c0e321538 patch: io, io/fs, os 2024-06-19 22:21:44 +08:00
xushiwei
1f67434c8c Merge pull request #360 from xushiwei/q
llgo/ssa/abi: PathOf fix - support trim PatchPathPrefix; typepatch fix: don't change patch pkg
2024-06-19 17:13:12 +08:00
xushiwei
6058b9851c llgo/ssa/abi: PathOf fix - support trim PatchPathPrefix 2024-06-19 17:06:56 +08:00
xushiwei
c586319978 typepatch fix: don't change patch pkg 2024-06-19 12:30:38 +08:00
xushiwei
0591fe0e8b Merge pull request #357 from luoliwoshang/readme/tips
README:update python &  install instructions
2024-06-19 11:25:51 +08:00
luoliwoshang
dabe3b17e6 README:update python & git install instructions 2024-06-18 23:18:25 +08:00
xushiwei
fbf50d45cb Merge pull request #351 from visualfc/instance
build: instantiate generics
2024-06-18 21:59:27 +08:00
visualfc
d59075e897 build: instantiate generics 2024-06-18 19:26:52 +08:00
xushiwei
2b491179f7 Merge pull request #346 from visualfc/checkindex
ssa: index/indexAddr check range
2024-06-18 18:52:19 +08:00
xushiwei
a62d17b1b1 Merge pull request #356 from luoliwoshang/readme/install
README:update install instruction of LLGOROOT
2024-06-18 18:50:37 +08:00
xushiwei
2431758218 Merge pull request #355 from xushiwei/q
cl: initFnNameOfHasPatch fix (should rename before funcOf)
2024-06-18 18:47:41 +08:00
luoliwoshang
b94586fdf4 README:update install instruction of LLGOROOT 2024-06-18 18:47:00 +08:00
xushiwei
a6b83d77bd cl: initFnNameOfHasPatch fix (should rename before funcOf) 2024-06-18 18:44:07 +08:00
xushiwei
43c55b36c8 Merge pull request #352 from xushiwei/q
cl: fn.SetRecover; patch library: call init
2024-06-18 18:35:33 +08:00
xushiwei
24c7928c4b cl: pkgFNoOldInit flag if no initFnNameOld 2024-06-18 18:32:29 +08:00
xushiwei
8c876c302a patch library: call init 2024-06-18 18:23:16 +08:00
xushiwei
778a4373ae cl: fn.SetRecover; inPatch/hasPatch 2024-06-18 17:33:37 +08:00
xushiwei
7a15cf1157 patch: errors (todo) 2024-06-18 13:50:55 +08:00
xushiwei
54e3210d7e Merge pull request #350 from xushiwei/q
c/pthread/sync: RWLock/Cond; sync: RWMutex/Cond/WaitGroup
2024-06-18 10:19:53 +08:00
xushiwei
a3197c12a8 testllgo: waitgroup 2024-06-18 10:17:05 +08:00
xushiwei
e7de841939 c/pthread/sync: RWLock/Cond; sync: RWMutex/Cond/WaitGroup 2024-06-18 10:14:29 +08:00
visualfc
29ba00f370 ssa: index/indexAddr check max 2024-06-18 07:13:57 +08:00
xushiwei
e35d70f338 Merge pull request #349 from xushiwei/q
c: c.Int/Uint not alias C.int/uint
2024-06-18 01:30:25 +08:00
xushiwei
0271c65ca2 c: c.Int/Uint not alias C.int/uint 2024-06-18 01:25:57 +08:00
xushiwei
e604524301 Merge pull request #348 from xushiwei/q
c/pthread/sync.Mutex; sync.Mutex/Once; globalType: support typepatch
2024-06-18 00:15:19 +08:00
xushiwei
298831d987 README: sync (partially) 2024-06-18 00:10:21 +08:00
xushiwei
3b2e97a729 globalType: support typepatch 2024-06-18 00:06:40 +08:00
xushiwei
edaba44c87 c/pthread/sync.Mutex; sync.Mutex/Once; typepatch.IsPatched 2024-06-17 23:51:40 +08:00
xushiwei
dc2dc910e8 Merge pull request #347 from visualfc/cfunc
cl: check context.inCFunc
2024-06-17 22:27:33 +08:00
visualfc
96bf260ce9 cl: check context.inCFunc 2024-06-17 21:41:49 +08:00
xushiwei
115ea4ccbb Merge pull request #343 from xushiwei/q
cl: compileFuncDecl/funcName fix; patch library: sync; build: patch library fix (link dependencies)
2024-06-17 19:39:44 +08:00
xushiwei
3fb400beb4 merge upstream 2024-06-17 19:33:27 +08:00
xushiwei
6442279a44 testlibgo: sync (to do) 2024-06-17 19:30:59 +08:00
xushiwei
592500cb0c build: patch library fix (link dependencies) 2024-06-17 18:58:01 +08:00
xushiwei
98f3e45c0a cl: compileFuncDecl/funcName fix; patch library: sync 2024-06-17 18:32:58 +08:00
xushiwei
e365196ee3 Merge pull request #342 from aofei/dependencies
README,ci: add Dependencies section and update install instructions accordingly
2024-06-17 18:17:32 +08:00
xushiwei
f656499c23 Merge pull request #334 from aofei/build
build: explicitly link libpthread for compatibility with glibc versions before 2.34
2024-06-17 18:15:41 +08:00
Aofei Sheng
180c019d2e README,ci: add Dependencies section and update install instructions accordingly
Fixes #340
2024-06-17 18:15:08 +08:00
Aofei Sheng
7db50921bc build: explicitly link libpthread for compatibility with glibc versions before 2.34
Fixes #329
2024-06-17 14:07:51 +08:00
xushiwei
257b3f3ee6 Merge pull request #330 from visualfc/ssa.index
ssa: fix ssa.Index and indexType
2024-06-17 12:53:07 +08:00
xushiwei
f7c69b6baf Merge pull request #338 from aofei/install
ci,README: improve install instructions
2024-06-17 12:48:51 +08:00
xushiwei
89a3b84ea1 Merge pull request #339 from xushiwei/q
c/pthread/sync.Once
2024-06-17 12:47:36 +08:00
xushiwei
bec29f99e6 x 2024-06-17 12:39:54 +08:00
xushiwei
72274bda82 c/pthread/sync.Once 2024-06-17 12:14:24 +08:00
Aofei Sheng
04b62a62cb ci,README: improve install instructions 2024-06-17 12:03:09 +08:00
xushiwei
ab7329d3eb Merge pull request #335 from xushiwei/q
build: LLGoFiles (support to compile c files)
2024-06-17 11:06:43 +08:00
xushiwei
a819796ce2 build: LLGoFiles (support to compile c files) 2024-06-17 11:02:52 +08:00
xushiwei
8c6cdcc97e pkgPath 2024-06-17 05:35:05 +08:00
xushiwei
bf0148e047 canSkipToBuild 2024-06-17 05:33:07 +08:00
xushiwei
bcf44b8ab2 Merge pull request #333 from xushiwei/q
patch sync/atomic; typepatch fix (don't change types)
2024-06-17 04:16:33 +08:00
xushiwei
ebc9711309 TestErrImport 2024-06-17 04:11:31 +08:00
xushiwei
4097f90938 testlibgo: atomic 2024-06-17 03:53:31 +08:00
xushiwei
d73f77affc README: sync/atomic 2024-06-17 03:52:05 +08:00
xushiwei
b4794dc541 patch sync/atomic; typepatch fix (don't change types) 2024-06-17 03:38:01 +08:00
xushiwei
5ee156057e Merge pull request #332 from xushiwei/q
llgo:skipall; patch runtime, sync, sync/atomic
2024-06-16 23:15:04 +08:00
xushiwei
68a63bb280 TestIgnoreName 2024-06-16 23:11:28 +08:00
xushiwei
815677863f Merge pull request #331 from aofei/build
build: force use of LLVM Linker (lld) and fix usage of -dead_strip on Linux
2024-06-16 23:09:49 +08:00
xushiwei
df2f13c9b6 patch runtime, sync (use llgo:skipall) 2024-06-16 23:07:42 +08:00
Aofei Sheng
3984037c98 build: force use of LLVM Linker (lld) and fix usage of -dead_strip on Linux 2024-06-16 23:04:14 +08:00
xushiwei
9c8570b37d buildAllPkgs fix 2024-06-16 22:47:57 +08:00
visualfc
f7cddb81df ssa: fix ssa.Index and indexType 2024-06-16 22:18:02 +08:00
xushiwei
dc1fbbf796 llgo:skipall 2024-06-16 21:32:11 +08:00
xushiwei
7b7b4e5f22 patch sync/atomic 2024-06-16 20:49:31 +08:00
xushiwei
8c9b0285e4 testrt: gotypes 2024-06-16 17:12:08 +08:00
xushiwei
3ff5caef94 Merge pull request #328 from xushiwei/q
llgo/ssa: AtomicCmpXchg fix
2024-06-16 17:07:20 +08:00
xushiwei
4a3446a0a5 llgo/ssa: AtomicCmpXchg fix 2024-06-16 17:03:41 +08:00
xushiwei
6f6d9b39ba Merge pull request #327 from xushiwei/q
atomic Load/Store
2024-06-16 16:47:19 +08:00
xushiwei
7d2f68c5e4 TestErrBuiltin 2024-06-16 16:44:22 +08:00
xushiwei
5416e92dbf atomic demo 2024-06-16 16:39:55 +08:00
xushiwei
340b5bd165 atomic Load/Store 2024-06-16 16:35:46 +08:00
xushiwei
fbd15a81b4 Merge pull request #322 from luoliwoshang/cjson-linux
【WIP】README:cjson/sqlite download for linux
2024-06-16 15:26:51 +08:00
xushiwei
039d0abce2 Merge pull request #326 from xushiwei/q
atomic, atomicCmpXchg
2024-06-16 15:25:58 +08:00
xushiwei
aefb65b1b8 x 2024-06-16 15:23:38 +08:00
xushiwei
f7c322c311 demo: c atomic 2024-06-16 15:20:29 +08:00
xushiwei
b5507f79e4 atomic, atomicCmpXchg 2024-06-16 03:49:09 +08:00
luoliwoshang
a2703ce51b README:cjson sqlite download 2024-06-16 00:56:06 +08:00
xushiwei
d48b12aa09 Merge pull request #325 from xushiwei/q
build: use -dead_strip to reduce app size
2024-06-16 00:34:13 +08:00
xushiwei
452c1fbfd4 build: use -dead_strip to reduce app size 2024-06-16 00:31:25 +08:00
xushiwei
f77fd2a944 Merge pull request #324 from xushiwei/q
packages.LoadEx: support Deduper
2024-06-15 23:32:20 +08:00
xushiwei
2b1da5b231 loadPackageEx: dedup 2024-06-15 23:27:41 +08:00
xushiwei
1b48b98e22 refineEx: Deduper 2024-06-15 23:03:38 +08:00
xushiwei
4af872ddd5 loadPackageEx 2024-06-15 22:56:17 +08:00
xushiwei
6614107192 refineEx 2024-06-15 22:34:31 +08:00
xushiwei
09e1f9addf rm defaultDriverEx 2024-06-15 21:12:43 +08:00
xushiwei
baf282ecb2 packages.LoadEx: support Deduper 2024-06-15 20:46:29 +08:00
xushiwei
6022b32227 Merge pull request #323 from xushiwei/q
cl.NewPackageEx: don't skip alt(patch) package
2024-06-15 19:27:24 +08:00
xushiwei
9e9b08a5a3 cl.NewPackageEx: don't skip alt(patch) package 2024-06-15 19:18:21 +08:00
xushiwei
8147b974aa Merge pull request #321 from xushiwei/q
patches of a standard library; testlibgo: math
2024-06-15 18:49:03 +08:00
xushiwei
0a5a0ef319 cl/ssa.SetDebug 2024-06-15 18:41:45 +08:00
xushiwei
00c73b8388 ci 2024-06-15 18:28:39 +08:00
xushiwei
dcb8eb7d6d TestCollectSkipNames 2024-06-15 18:22:26 +08:00
xushiwei
7f11651311 TestGoLibMath: mac only (temp) 2024-06-15 18:08:08 +08:00
xushiwei
71518b025d TestGoLibMath: set LLGOROOT 2024-06-15 18:02:51 +08:00
xushiwei
287722b1d2 setPkgSSA 2024-06-15 17:56:45 +08:00
xushiwei
3a6f5dd4ee createAltSSAPkg 2024-06-15 17:40:05 +08:00
xushiwei
4aa3d321fa cltest.InitDebug 2024-06-15 16:26:37 +08:00
xushiwei
abb04b177c Merge remote-tracking branch 'gop/main' into q 2024-06-15 16:12:02 +08:00
xushiwei
764e0f0e7f TestGoLibMath 2024-06-15 16:08:10 +08:00
xushiwei
b668175c62 go package demo: math 2024-06-15 15:58:22 +08:00
xushiwei
5011c394d7 build: use typepatch.Pkg merge patches of a standard library 2024-06-15 15:52:44 +08:00
xushiwei
994502077a cl: collectSkipNames; processPkg bugfix 2024-06-15 14:56:03 +08:00
xushiwei
7d8bed16b0 createAltSSAPkg 2024-06-15 13:08:11 +08:00
xushiwei
a45be62b68 cl.NewPackageEx 2024-06-15 12:43:05 +08:00
xushiwei
e0a25b5098 NewPackage: altSSA 2024-06-15 12:10:08 +08:00
xushiwei
fa712aa3a0 build: aPackage.AltPkg/AltSSA 2024-06-15 11:44:52 +08:00
xushiwei
1599ba0294 private closureCtx/closureStub 2024-06-15 10:41:28 +08:00
xushiwei
94d567bf8f testlibgo: math 2024-06-15 10:24:10 +08:00
xushiwei
17f17bcc9e Merge pull request #320 from xushiwei/q
c/math; internal/lib/math
2024-06-15 10:05:23 +08:00
xushiwei
12c262621e c/sqlite: use pkg-config 2024-06-15 10:02:54 +08:00
xushiwei
dd35f2c14d c/math; internal/lib/math 2024-06-15 09:58:32 +08:00
xushiwei
66a9fd928a Merge pull request #319 from xushiwei/q
rm internal/runtime/c; mv internal/runtime/bdwgc => c/bdwgc
2024-06-15 08:50:34 +08:00
xushiwei
da82e5dd04 c/bdwgc 2024-06-15 08:47:13 +08:00
xushiwei
98498c9180 rm internal/runtime/c; mv internal/runtime/bdwgc => c/bdwgc 2024-06-15 08:43:48 +08:00
xushiwei
7b0ed42d3b Merge pull request #318 from xushiwei/q
internal/abi.Map: IndirectKey/IndirectElem
2024-06-15 08:28:20 +08:00
xushiwei
3e4fbde0b4 llgo/ssa: mv Range/Next => datastruct.go 2024-06-15 08:25:50 +08:00
xushiwei
7b0d23f91f internal/abi.Map: IndirectKey/IndirectElem 2024-06-15 08:21:27 +08:00
xushiwei
08d00fa234 Merge pull request #313 from visualfc/globals
ssa: global use elem type
2024-06-15 06:59:06 +08:00
xushiwei
2e32d9806f Merge pull request #315 from visualfc/abi
runtime: expand abi array
2024-06-15 06:55:41 +08:00
visualfc
6e73fbf65e runtime: expand abi array 2024-06-15 06:48:16 +08:00
xushiwei
b9f74d349c Merge pull request #317 from goplus/revert-316-q
Revert "runtime: map; llgo/ssa: MapUpdate"
2024-06-14 22:52:56 +08:00
xushiwei
5e45e38481 Revert "runtime: map; llgo/ssa: MapUpdate" 2024-06-14 22:50:23 +08:00
xushiwei
78b8455bba Merge pull request #316 from xushiwei/q
runtime: map; llgo/ssa: MapUpdate
2024-06-14 22:41:38 +08:00
xushiwei
6f71885aa2 TestMapUpdate 2024-06-14 22:37:46 +08:00
xushiwei
e107567997 llgo/ssa: MapUpdate fix 2024-06-14 22:33:40 +08:00
xushiwei
8d42acec16 disable llgo test temp 2024-06-14 22:14:18 +08:00
xushiwei
33d73eaecd llgo/ssa: abiMapOf 2024-06-14 22:07:48 +08:00
xushiwei
47b20b01d0 runtime: map; llgo/ssa: MapUpdate 2024-06-14 21:57:34 +08:00
xushiwei
b94cf700b4 Merge pull request #314 from luoliwoshang/link-cjson
llgo/x/cjson:link cjson by pkg-config
2024-06-14 19:11:01 +08:00
luoliwoshang
a26d30be3c llgo/x/cjson:link cjson by pkg-config 2024-06-14 11:36:48 +08:00
visualfc
ec1cca7ca4 ssa: global use elem type 2024-06-14 10:09:46 +08:00
visualfc
0c321c8c98 ssa: binop equal(func,slice,array,struct) and buildConstStr 2024-06-14 10:04:01 +08:00
xushiwei
7a54967bee runtime: map 2024-06-13 22:58:04 +08:00
xushiwei
f3b6d25aaa Merge pull request #309 from xushiwei/q
README: recover
2024-06-13 17:12:33 +08:00
xushiwei
419133d3e1 README: recover 2024-06-13 17:11:58 +08:00
xushiwei
1402ff371e Merge pull request #308 from aofei/README.md
README: fix LLGO_LIB_PYTHON instruction
2024-06-13 16:51:54 +08:00
Aofei Sheng
ee2d67c151 README: fix LLGO_LIB_PYTHON instruction 2024-06-13 15:40:35 +08:00
xushiwei
a8f1db0db1 Merge pull request #307 from xushiwei/q
recover
2024-06-13 13:55:07 +08:00
xushiwei
4abcbb9b51 recover 2024-06-13 13:51:36 +08:00
xushiwei
e33dd8acc3 Merge pull request #304 from xushiwei/q
testlibgo: math => mathbits
2024-06-13 07:33:46 +08:00
xushiwei
64e96cc101 testlibgo: math => mathbits 2024-06-13 07:30:08 +08:00
xushiwei
1aaa737dd6 Merge pull request #303 from xushiwei/q
llgo/ssa: float Const fix; cl: replace runtime => llgo/internal/runtime
2024-06-13 03:10:40 +08:00
xushiwei
31e3fc9060 x 2024-06-13 03:04:18 +08:00
xushiwei
b70b868552 TestReplaceGoName 2024-06-13 03:00:55 +08:00
xushiwei
7235357ef5 runtime: TODO - error var; cl: link goVar 2024-06-13 02:53:54 +08:00
xushiwei
18eecbe9f4 llgo/ssa: float Const fix; cl: replaceGoName runtime => llgo/internal/runtime 2024-06-13 00:56:18 +08:00
xushiwei
505525134f Merge pull request #302 from xushiwei/q
README: panic/defer
2024-06-12 23:28:30 +08:00
xushiwei
7dd740f51a README: panic/defer 2024-06-12 23:27:54 +08:00
xushiwei
3d590f8eb6 Merge pull request #301 from xushiwei/q
llgo/ssa: defer support panic; IndirectJump; runtime.Rethrow
2024-06-12 23:19:52 +08:00
xushiwei
42a5c6a19f c.GoDeferData; llgo/ssa: rm excepKey 2024-06-12 23:17:10 +08:00
xushiwei
2c4f6063a6 disable LLGO tests on ubuntu 2024-06-12 22:56:36 +08:00
xushiwei
845767b1d7 x 2024-06-12 21:13:47 +08:00
xushiwei
3e144af127 skip defer 2024-06-12 21:09:30 +08:00
xushiwei
45f470e3a7 merge upstream 2024-06-12 21:02:26 +08:00
xushiwei
42a5c60af6 runtime.Rethrow fix; llgo/ssa: IndirectJump fix 2024-06-12 20:53:30 +08:00
xushiwei
29cebd1e1f Merge pull request #300 from xushiwei/t
fix #294
2024-06-12 20:35:17 +08:00
xushiwei
4450f5a084 fix #294 2024-06-12 20:31:42 +08:00
xushiwei
b8230e144a Merge pull request #298 from visualfc/eface
ssa: interface equal
2024-06-12 20:29:15 +08:00
xushiwei
d500902eff TODO: noreturn 2024-06-12 17:38:29 +08:00
xushiwei
b787de0163 runtime: rethrow/panic; llgo/ssa: DeferData; Null => Nil 2024-06-12 17:26:07 +08:00
visualfc
2f0d525c2e ssa: binop EfaceEqual 2024-06-12 07:25:20 +08:00
visualfc
3f0c65ebb2 ssa: fix typeAssert for Nil 2024-06-11 20:50:01 +08:00
visualfc
f33796797d cl: _testgo/reader 2024-06-11 12:15:18 +08:00
xushiwei
68a09b9804 Merge pull request #299 from xushiwei/t
cl: isVargs support defer/go
2024-06-11 10:39:40 +08:00
xushiwei
5e5d149ca5 cl: isVargs support defer/go 2024-06-11 10:35:27 +08:00
visualfc
bdf1c275c4 ssa: interface equal 2024-06-11 10:24:30 +08:00
visualfc
439a69f413 ssa: fix cvtNamed 2024-06-11 10:23:36 +08:00
visualfc
a14974fbf2 cl: compile ssa.Field 2024-06-11 10:23:00 +08:00
xushiwei
1ecd9af2e1 Merge pull request #297 from cpunion/decl-test
cl: test decl only pkg kind
2024-06-11 08:28:41 +08:00
Li Jie
c8cc2dac04 cl: test decl only pkg kind 2024-06-09 19:23:22 +08:00
xushiwei
60dd33b48f llgo/ssa: defer support panic; IndirectJump/Switch 2024-06-09 09:08:22 +08:00
xushiwei
8b7d8b7786 Merge pull request #292 from xushiwei/q
disable gc: llgo -tags nogc
2024-06-08 23:12:34 +08:00
xushiwei
fb7ea7810e disable gc: llgo -tags nogc 2024-06-08 23:06:55 +08:00
xushiwei
508e16aa80 Merge pull request #291 from xushiwei/q
README: gc
2024-06-08 22:35:25 +08:00
xushiwei
a057db8756 README: gc 2024-06-08 22:30:06 +08:00
xushiwei
a1c588bde8 Merge pull request #284 from cpunion/bdwgc
Add bdwgc
2024-06-08 22:12:57 +08:00
xushiwei
9b17fdeae2 Merge pull request #290 from xushiwei/q
llgo/ssa: deferInitBuilder
2024-06-08 21:46:47 +08:00
xushiwei
29c0c737ed llgo/ssa: deferInitBuilder 2024-06-08 21:39:45 +08:00
xushiwei
be6986a7f6 Merge pull request #289 from xushiwei/q
llgo/ssa: getDefer fix
2024-06-08 20:15:07 +08:00
xushiwei
63c03bb28c llgo/ssa: getDefer fix 2024-06-08 20:09:56 +08:00
xushiwei
758f5b27c3 Merge pull request #288 from xushiwei/q
runtime.Defer: remove proc
2024-06-08 16:34:48 +08:00
xushiwei
32bfb3d57e runtime.Defer: remove proc 2024-06-08 16:31:52 +08:00
xushiwei
6bd8822a90 Merge pull request #287 from xushiwei/q
builtin: sigjmpbuf/sigsetjmp/siglongjmp
2024-06-08 15:19:56 +08:00
xushiwei
abf461a049 TestErrBuiltin 2024-06-08 15:17:49 +08:00
xushiwei
4e98055b9c TestFromTestlibc 2024-06-08 15:09:24 +08:00
xushiwei
e6ab5bd86d testFrom: expected == ';' means skipping out.ll 2024-06-08 15:04:35 +08:00
xushiwei
02e0651eab ignore setjmp/out.ll (os deps) 2024-06-08 14:59:26 +08:00
xushiwei
93be634673 builtin: sigjmpbuf/sigsetjmp/siglongjmp 2024-06-08 14:49:48 +08:00
xushiwei
a1978f661b Merge pull request #286 from xushiwei/t
llgo/ssa: eh.go (exception handling)
2024-06-08 13:34:30 +08:00
xushiwei
9bda864fed Merge remote-tracking branch 'gop/main' into q 2024-06-08 13:31:41 +08:00
xushiwei
b6903c6b99 llgo/ssa: eh.go (exception handling) 2024-06-08 13:31:11 +08:00
xushiwei
1e7394135d Merge pull request #285 from xushiwei/q
_demo: setjmp
2024-06-08 13:25:33 +08:00
Li Jie
61ccaab55b ci: show test result 2024-06-08 13:20:53 +08:00
xushiwei
f17c3c52c4 gitignore demo.ll 2024-06-08 13:12:32 +08:00
Li Jie
f16e721d01 ci: comment test result on PR 2024-06-08 13:11:24 +08:00
xushiwei
6dfdca2d19 _demo: setjmp 2024-06-08 13:10:59 +08:00
Li Jie
ee848e66ac test: run _demo/* and _pydemo/* 2024-06-08 13:10:20 +08:00
Li Jie
91e1fa6aff test: simple llgo tests 2024-06-08 10:15:28 +08:00
Li Jie
6049cf9047 runtime: add bdwgc 2024-06-08 10:15:28 +08:00
xushiwei
e91366c328 Merge pull request #282 from visualfc/runtime
build: check runtime link file
2024-06-08 07:54:00 +08:00
xushiwei
d6a5aaf4ad Merge pull request #283 from xushiwei/q
setjmp/trycatch
2024-06-08 00:13:06 +08:00
xushiwei
fcf3f2abc7 setjmp/trycatch 2024-06-08 00:08:29 +08:00
visualfc
ae77622026 build: build runtime check skip 2024-06-07 21:02:01 +08:00
visualfc
878b395e20 build: check runtime link file 2024-06-07 20:33:31 +08:00
xushiwei
92aee9b69c Merge pull request #281 from visualfc/build
build: build runtime local
2024-06-07 17:07:15 +08:00
visualfc
fe10ddc720 build: build runtime local 2024-06-07 15:25:35 +08:00
xushiwei
46899f042f Merge pull request #280 from xushiwei/q
demo: try..catch
2024-06-07 14:29:59 +08:00
xushiwei
d4249da131 demo: try..catch 2024-06-07 14:29:16 +08:00
xushiwei
6cae018066 Merge pull request #279 from xushiwei/q
c/setjmp/demo
2024-06-07 14:13:18 +08:00
xushiwei
95c1886df5 c/setjmp/demo 2024-06-07 14:12:35 +08:00
xushiwei
fbd8cb07ea Merge pull request #278 from xushiwei/q
c/setjmp
2024-06-07 13:51:10 +08:00
xushiwei
4868903844 c/setjmp 2024-06-07 13:48:36 +08:00
xushiwei
62e721b1c8 Merge pull request #276 from cpunion/libc
runtime: fix alias no effects on linux
2024-06-06 22:33:19 +08:00
Li Jie
1ceaf1df22 runtime: fix libc linking 2024-06-06 19:46:21 +08:00
xushiwei
21c9f7b7fb Merge pull request #275 from cpunion/libc
runtime: libc compatible
2024-06-06 17:24:06 +08:00
Li Jie
f5526f73c7 runtime: compatible difference of stdio symbols between linux and others 2024-06-06 17:17:26 +08:00
Li Jie
15fad2e841 cl: supports decl: <param> 2024-06-06 17:14:31 +08:00
xushiwei
3ecb43072d Merge pull request #272 from visualfc/typeassert
ssa: typeAssert support interface
2024-06-06 10:26:31 +08:00
visualfc
2fce2318ed ssa: set method.name to pkg.name if private 2024-06-06 07:30:59 +08:00
xushiwei
226fd29af8 Merge pull request #274 from xushiwei/q
ssa/python.go
2024-06-05 16:33:19 +08:00
xushiwei
c48b39baab ssa/python.go 2024-06-05 16:29:58 +08:00
xushiwei
ed19a6960e Merge pull request #273 from xushiwei/q
cl/blocks
2024-06-05 15:20:08 +08:00
xushiwei
11b4de63ee llgo_autogen.lla 2024-06-05 15:14:34 +08:00
xushiwei
b9d1d52ab3 gentests 2024-06-05 15:10:35 +08:00
xushiwei
fe548e580d use cl/blocks 2024-06-05 15:08:05 +08:00
xushiwei
fd7d2765c8 findLoop: reach 2024-06-05 15:02:11 +08:00
xushiwei
a226a70383 findLoop: mark fdel 2024-06-05 14:14:12 +08:00
xushiwei
519e69a7f8 cl/blocks 2024-06-05 13:48:11 +08:00
xushiwei
3d599f8044 Merge pull request #271 from goplus/dependabot/go_modules/golang.org/x/tools-0.22.0
build(deps): bump golang.org/x/tools from 0.21.0 to 0.22.0
2024-06-05 10:05:43 +08:00
dependabot[bot]
bbf0393008 build(deps): bump golang.org/x/tools from 0.21.0 to 0.22.0
Bumps [golang.org/x/tools](https://github.com/golang/tools) from 0.21.0 to 0.22.0.
- [Release notes](https://github.com/golang/tools/releases)
- [Commits](https://github.com/golang/tools/compare/v0.21.0...v0.22.0)

---
updated-dependencies:
- dependency-name: golang.org/x/tools
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-06-05 00:52:06 +00:00
xushiwei
f1a4af013a Merge pull request #270 from xushiwei/q
llgo/ssa: NoArgsNoRet
2024-06-04 20:03:49 +08:00
xushiwei
05af9f9810 llgo/ssa: NoArgsNoRet 2024-06-04 20:02:45 +08:00
xushiwei
f68aada9f8 Merge pull request #269 from cpunion/link-args
build: support pkg-config and link args
2024-06-04 19:22:48 +08:00
Li Jie
52d60d9623 build: support pkg-config and link args 2024-06-04 16:35:17 +08:00
xushiwei
2ddf8a44bc Merge pull request #268 from visualfc/cast
cl: fix cl/_testrt/cast
2024-06-04 15:43:53 +08:00
visualfc
281fbc2bee cl: fix cl/_testrt/cast 2024-06-04 15:27:49 +08:00
xushiwei
c174568081 Merge pull request #266 from xushiwei/q
c/sqlite
2024-06-04 12:55:30 +08:00
xushiwei
f4a519c824 c/sqlite 2024-06-04 12:48:49 +08:00
xushiwei
62e4e2f716 Merge pull request #258 from visualfc/invoke
ssa: MakeInterface check abi.KindDirectIface
2024-06-04 10:35:38 +08:00
visualfc
193e6dfc93 ssa: ChangeInterface 2024-06-03 16:03:05 +08:00
visualfc
7596658e6c ssa: MakeInterface check abi.KindDirectIface 2024-06-03 11:47:16 +08:00
xushiwei
73d6bd8400 Merge pull request #264 from xushiwei/q
llgo/ssa getDefer fix: move to function start
2024-06-03 09:58:55 +08:00
xushiwei
922fabd935 llgo/ssa getDefer fix: move to function start 2024-06-03 09:56:39 +08:00
xushiwei
2f3d267439 Merge pull request #263 from xushiwei/q
llgo/ssa: DeferAlways/DeferInCond/DeferInLoop
2024-06-03 08:46:24 +08:00
xushiwei
bdaf7ff30b Merge remote-tracking branch 'gop/main' into q 2024-06-03 08:43:34 +08:00
xushiwei
cfca98512a llgo/ssa: DeferAlways/DeferInCond/DeferInLoop 2024-06-03 02:43:04 +08:00
xushiwei
23d9e86c46 Merge pull request #262 from xushiwei/q
README: defer
2024-06-03 01:43:43 +08:00
xushiwei
6ac6fb0192 README: defer 2024-06-03 01:43:17 +08:00
xushiwei
aaa36b9d3b Merge pull request #261 from xushiwei/q
defer support; llgo/ssa: IfThen/RunDefers/EndBuild
2024-06-03 01:35:33 +08:00
xushiwei
2c799a8ccf deferInit bugfix 2024-06-03 01:32:25 +08:00
xushiwei
56a5a7d72e defer refactor 2024-06-03 01:06:01 +08:00
xushiwei
410f9dd759 llgo/ssa: EndBuild 2024-06-02 21:54:51 +08:00
xushiwei
ba45217756 llgo/ssa: RunDefers 2024-06-02 15:24:42 +08:00
xushiwei
5a5929048d defer support; llgo/ssa: IfThen 2024-06-02 14:29:35 +08:00
xushiwei
bfc3c7fbf9 Merge pull request #257 from xushiwei/q
llgo/ssa: Builtin
2024-06-01 17:33:01 +08:00
xushiwei
e151bd4cd1 TestUserdefExpr 2024-06-01 17:30:37 +08:00
xushiwei
bfe68520f4 logCall: ignore vkBuiltin 2024-06-01 17:26:42 +08:00
xushiwei
45734c0b5c llgo/ssa: Builtin 2024-06-01 17:18:17 +08:00
xushiwei
d689062fc3 Merge pull request #256 from xushiwei/q
README: goroutine
2024-06-01 16:17:24 +08:00
xushiwei
881574ed39 README: goroutine 2024-06-01 16:14:26 +08:00
xushiwei
0bd5aa873b Merge pull request #255 from xushiwei/q
goroutine support; llgo/ssa: memory (malloc/free)
2024-06-01 16:09:31 +08:00
xushiwei
51f3ac2376 _testgo: goroutine 2024-06-01 16:04:35 +08:00
xushiwei
e5802853c0 goroutine support; llgo/ssa: memory (malloc/free) 2024-06-01 15:52:54 +08:00
xushiwei
edb5e36916 Merge pull request #254 from xushiwei/q
c/pthread
2024-05-31 20:07:00 +08:00
xushiwei
33ba94e784 c/pthread 2024-05-31 20:02:59 +08:00
xushiwei
9c969e0026 Merge pull request #252 from visualfc/fnnamed
ssa: fix llvm named in func
2024-05-31 16:26:25 +08:00
visualfc
858622a98d move eface demo to cl/_testrt 2024-05-31 15:53:52 +08:00
visualfc
c673489461 ssa: fix llvm named in func 2024-05-31 14:22:17 +08:00
xushiwei
53a39b6947 Merge pull request #251 from xushiwei/q
llgo/ssa: Do Call/Go/Defer
2024-05-31 12:06:09 +08:00
xushiwei
8f82d86a5d llgo/ssa: Do Call/Go/Defer 2024-05-31 12:01:11 +08:00
397 changed files with 45679 additions and 4476 deletions

View File

@@ -11,19 +11,38 @@ on:
jobs:
test-macos:
runs-on: macos-latest
test:
strategy:
matrix:
os: [macos-latest, ubuntu-latest]
llvm: [17]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v4
- name: Update Homebrew
if: matrix.llvm == 17 # needed as long as LLVM 17 is still fresh
# needed as long as LLVM 17 is still fresh
if: matrix.llvm == 17 && startsWith(matrix.os, 'macos')
run: brew update
- name: Install LLVM ${{ matrix.llvm }}
run: HOMEBREW_NO_AUTO_UPDATE=1 brew install llvm@${{ matrix.llvm }}
- name: Install LLVM ${{ matrix.llvm }} and bdw-gc
if: startsWith(matrix.os, 'macos')
run: |
HOMEBREW_NO_AUTO_UPDATE=1 brew install llvm@${{ matrix.llvm }} bdw-gc
echo `brew --prefix llvm@${{ matrix.llvm }}`/bin >> $GITHUB_PATH
- name: Install LLVM ${{ matrix.llvm }} and libgc-dev
if: startsWith(matrix.os, 'ubuntu')
run: |
echo "deb http://apt.llvm.org/$(lsb_release -cs)/ llvm-toolchain-$(lsb_release -cs)-${{ matrix.llvm }} main" | sudo tee /etc/apt/sources.list.d/llvm.list
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
sudo apt-get update
sudo apt-get install -y llvm-${{ matrix.llvm }}-dev clang-${{ matrix.llvm }} lld-${{ matrix.llvm }} pkg-config libgc-dev libcjson-dev libsqlite3-dev python3.11-dev
echo /usr/lib/llvm-${{ matrix.llvm }}/bin >> $GITHUB_PATH
- name: Clang information
run: |
echo $PATH
which clang
clang --version
- name: Set up Go
uses: actions/setup-go@v5
@@ -34,36 +53,40 @@ jobs:
run: go build -v ./...
- name: Test
if: matrix.os != 'macos-latest'
run: go test -v ./...
test-linux:
runs-on: ubuntu-20.04
strategy:
matrix:
llvm: [17]
steps:
- uses: actions/checkout@v4
- name: Test with coverage
if: matrix.os == 'macos-latest'
run: go test -v -coverprofile="coverage.txt" -covermode=atomic ./...
- name: Install LLVM ${{ matrix.llvm }}
run: |
echo 'deb http://apt.llvm.org/focal/ llvm-toolchain-focal-${{ matrix.llvm }} main' | sudo tee /etc/apt/sources.list.d/llvm.list
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
sudo apt-get update
sudo apt-get install --no-install-recommends llvm-${{ matrix.llvm }}-dev
- name: Install
run: go install ./...
- name: LLGO tests
if: matrix.os != 'ubuntu-latest'
run: |
echo "Test result on ${{ matrix.os }} with LLVM ${{ matrix.llvm }}" > result.md
LLGOROOT=$PWD bash .github/workflows/test_llgo.sh
- name: Test _demo and _pydemo
run: |
set +e
LLGOROOT=$PWD bash .github/workflows/test_demo.sh
exit 0
- name: Show test result
run: cat result.md
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '1.20'
- name: PR comment with test result
uses: thollander/actions-comment-pull-request@v2
if: false
with:
filePath: result.md
comment_tag: test-result-on-${{ matrix.os }}-with-llvm-${{ matrix.llvm }}
- name: Build
run: go build -v ./...
- name: Test
run: go test -v -coverprofile="coverage.txt" -covermode=atomic ./...
- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
slug: goplus/llgo
- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v4
with:
token: ${{ secrets.CODECOV_TOKEN }}
slug: goplus/llgo

29
.github/workflows/test_demo.sh vendored Normal file
View File

@@ -0,0 +1,29 @@
#!/bin/bash
# llgo run subdirectories under _demo and _pydemo
total=0
failed=0
failed_cases=""
for d in ./_demo/* ./_pydemo/*; do
total=$((total+1))
if [ -d "$d" ]; then
echo "Testing $d"
if ! llgo run -v "$d"; then
echo "FAIL"
failed=$((failed+1))
failed_cases="$failed_cases\n* :x: $d"
else
echo "PASS"
fi
fi
done
echo "=== Done"
echo "$((total-failed))/$total tests passed"
if [ "$failed" -ne 0 ]; then
echo ":bangbang: Failed demo cases:" | tee -a result.md
echo -e "$failed_cases" | tee -a result.md
exit 1
else
echo ":white_check_mark: All demo tests passed" | tee -a result.md
fi

38
.github/workflows/test_llgo.sh vendored Normal file
View File

@@ -0,0 +1,38 @@
#!/bin/bash
set -e
export LLGOROOT=$PWD
testcmd=/tmp/test
llgo build -o $testcmd ./_test
cases=$($testcmd)
total=$(echo "$cases" | wc -l | tr -d ' ')
failed=0
failed_cases=""
for idx in $(seq 1 $((total))); do
case=$(echo "$cases" | sed -n "${idx}p")
case_name=$(echo "$case" | cut -d',' -f2)
echo "=== Test case: $case_name"
set +e
out=$("$testcmd" "$((idx-1))" 2>&1)
exit_code=$?
set -e
if [ "${exit_code:-0}" -ne 0 ]; then
echo "failed: $out"
failed=$((failed+1))
failed_cases="$failed_cases\n* :x: $case_name"
else
echo "passed"
fi
done
echo "=== Done"
echo "$((total-failed))/$total tests passed"
if [ "$failed" -ne 0 ]; then
echo ":bangbang: Failed llgo cases:" | tee -a result.md
echo -e "$failed_cases" | tee -a result.md
exit 1
else
echo ":white_check_mark: All llgo tests passed" | tee -a result.md
fi

4
.gitignore vendored
View File

@@ -9,7 +9,8 @@
*.dylib
test.db
llgo_autogen.ll
demo.ll
llgo_autogen*.ll
stories*.bin
.DS_Store
err.log
@@ -18,6 +19,7 @@ numpy.txt
_go/
_runtime/
_tinygo/
_output/
build.dir/
.vscode/

View File

@@ -34,7 +34,6 @@ The `_demo` directory contains some C standard libary related demos (it start wi
To run these demos (If you haven't installed `llgo` yet, please refer to [How to install](#how-to-install)):
```sh
export LLGOROOT=`pwd`
cd <demo-directory> # eg. cd _demo/hello
llgo run .
```
@@ -60,6 +59,8 @@ And you can import any Python library into `llgo` through a program called `llpy
* [pytorch](https://pkg.go.dev/github.com/goplus/llgo/py/torch)
* [matplotlib](https://pkg.go.dev/github.com/goplus/llgo/py/matplotlib)
Note: For third-party libraries (such as pandas and pytorch), you still need to install the library files.
Here is an example using the Python `math` library:
```go
@@ -129,10 +130,10 @@ You can also specify the path to tell `llgo` where the Python library is located
export LLGO_LIB_PYTHON=/foo/bar/python3.12
```
For example, `/opt/homebrew/Frameworks/Python.framework/Versions/3.12/libpython3.12.dylib` is a typical python library location under macOS. So we should set it like this:
For example, `/opt/homebrew/Frameworks/Python.framework/Versions/3.12/lib/libpython3.12.dylib` is a typical python library location under macOS. So we should set it like this:
```sh
export LLGO_LIB_PYTHON=/opt/homebrew/Frameworks/Python.framework/Versions/3.12/python3.12
export LLGO_LIB_PYTHON=/opt/homebrew/Frameworks/Python.framework/Versions/3.12/lib/python3.12
```
Note that the file name must be written in a platform-independent format, using `python3.12` instead of `libpython3.12.dylib`.
@@ -140,7 +141,6 @@ Note that the file name must be written in a platform-independent format, using
Then you can run the demos:
```sh
export LLGOROOT=`pwd`
cd <demo-directory> # eg. cd _pydemo/callpy
llgo run .
```
@@ -167,22 +167,33 @@ Here are some examples related to them:
## Go syntax support
Common Go syntax is already supported. Except for the following, which needs to be improved:
Most of the Go syntax is already supported. Except for the following, which needs to be improved:
* map (Very limited support)
* panic (Limited support)
* recover (Not supported yet)
* defer (Not supported yet)
* gc (Not supported yet)
* chan (Not supported yet)
* goroutine (Not supported yet)
* generics (Not supported yet)
Here are some examples related to Go syntax:
* [concat](_demo/concat/concat.go): define a variadic function
* [genints](_demo/genints/genints.go): various forms of closure usage (including C function, recv.method and anonymous function)
* [errors](_demo/errors/errors.go): demo to implement error interface
* [errors](_cmptest/errors/errors.go): demo to implement error interface
* [defer](_cmptest/defer/defer.go): defer demo
* [goroutine](_demo/goroutine/goroutine.go): goroutine demo
## Defer
LLGo `defer` does not support usage in loops. This is not a bug but a feature, because we think that using `defer` in a loop is a very unrecommended practice.
### Garbage Collection (GC)
By default, LLGo implements `gc` based on [bdwgc](https://www.hboehm.info/gc/) (also known as [libgc](https://www.hboehm.info/gc/)).
However, you can disable gc by specifying the `nogc` tag. For example:
```sh
llgo run -tags nogc .
```
## Go packages support
@@ -193,8 +204,35 @@ Here are the Go packages that can be imported correctly:
* [unicode](https://pkg.go.dev/unicode)
* [unicode/utf8](https://pkg.go.dev/unicode/utf8)
* [unicode/utf16](https://pkg.go.dev/unicode/utf16)
* [math](https://pkg.go.dev/math)
* [math/bits](https://pkg.go.dev/math/bits)
* [math/cmplx](https://pkg.go.dev/math/cmplx)
* [sort](https://pkg.go.dev/sort)
* [strconv](https://pkg.go.dev/strconv)
* [sync/atomic](https://pkg.go.dev/sync/atomic)
* [sync](https://pkg.go.dev/sync) (partially)
* [syscall](https://pkg.go.dev/syscall) (partially)
* [errors](https://pkg.go.dev/errors) (partially)
* [io](https://pkg.go.dev/io) (partially)
* [io/fs](https://pkg.go.dev/io/fs) (partially)
* [os](https://pkg.go.dev/os) (partially)
* [fmt](https://pkg.go.dev/fmt) (partially)
* [reflect](https://pkg.go.dev/reflect) (partially)
* [time](https://pkg.go.dev/time) (partially)
## Dependencies
- [Go 1.20+](https://go.dev) (build only)
- [LLVM 17](https://llvm.org)
- [LLD 17](https://lld.llvm.org)
- [Clang 17](https://clang.llvm.org)
- [pkg-config 0.29+](https://www.freedesktop.org/wiki/Software/pkg-config/)
- [bdwgc/libgc 8.0+](https://www.hboehm.info/gc/)
- [cJSON 1.7+](https://github.com/DaveGamble/cJSON) (optional, for [`github.com/goplus/llgo/c/cjson`](https://pkg.go.dev/github.com/goplus/llgo/c/cjson))
- [SQLite 3](https://www.sqlite.org) (optional, for [`github.com/goplus/llgo/c/sqlite`](https://pkg.go.dev/github.com/goplus/llgo/c/sqlite))
- [Python 3.11+](https://www.python.org) (optional, for [`github.com/goplus/llgo/py`](https://pkg.go.dev/github.com/goplus/llgo/py))
## How to install
Follow these steps to generate the `llgo` command (its usage is the same as the `go` command):
@@ -202,18 +240,30 @@ Follow these steps to generate the `llgo` command (its usage is the same as the
### on macOS
```sh
brew update # execute if needed
brew install llvm@17
brew update # execute if needed
brew install llvm@17 pkg-config libgc
brew install cjson sqlite python@3.12 # optional
export PATH=$(brew --prefix llvm@17)/bin:$PATH # you may want to add this to your shell RC file, e.g. ~/.zshrc
export CC=clang CXX=clang++ # only for go build; optional if you have other compatible compilers
git clone https://github.com/goplus/llgo.git
cd llgo
export LLGOROOT="/path/to/llgo" # Replace this with the root directory of the llgo project
go install -v ./...
```
### on Linux
### on Linux (Debian/Ubuntu)
```sh
echo 'deb http://apt.llvm.org/focal/ llvm-toolchain-focal-17 main' | sudo tee /etc/apt/sources.list.d/llvm.list
echo "deb http://apt.llvm.org/$(lsb_release -cs)/ llvm-toolchain-$(lsb_release -cs)-17 main" | sudo tee /etc/apt/sources.list.d/llvm.list
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
sudo apt-get update # execute if needed
sudo apt-get install --no-install-recommends llvm-17-dev
sudo apt-get update # execute if needed
sudo apt-get install -y llvm-17-dev clang-17 lld-17 pkg-config libgc-dev
sudo apt-get install -y libcjson-dev libsqlite3-dev python3.12-dev # optional
export PATH=/usr/lib/llvm-17/bin:$PATH # you may want to add this to your shell RC file, e.g. ~/.bashrc
export CC=clang CXX=clang++ # only for go build; optional if you have other compatible compilers
git clone https://github.com/goplus/llgo.git
cd llgo
export LLGOROOT="/path/to/llgo" # Replace this with the root directory of the llgo project
go install -v ./...
```
@@ -233,6 +283,7 @@ TODO
How do I generate these tools?
```sh
export CC=clang CXX=clang++ # only for go build; optional if you have other compatible compilers
go install -v ./... # compile all tools except pydump
cd chore/_xtool
llgo install ./... # compile pydump

11
_cmptest/chan/chan.go Normal file
View File

@@ -0,0 +1,11 @@
package main
func main() {
ch := make(chan int, 10)
println(len(ch), cap(ch))
go func() {
ch <- 100
}()
n, ok := <-ch
println(n, ok)
}

17
_cmptest/defer/defer.go Normal file
View File

@@ -0,0 +1,17 @@
package main
func f(s string) bool {
return len(s) > 2
}
func main() {
defer func() {
println("hi")
}()
if s := "hello"; f(s) {
defer println(s)
} else {
defer println("world")
}
defer println("bye")
}

View File

@@ -17,6 +17,5 @@ func (e *errorString) Error() string {
func main() {
err := New("an error")
println(err)
println(err.Error())
}

7
_cmptest/fmtdemo/fmt.go Normal file
View File

@@ -0,0 +1,7 @@
package main
import "fmt"
func main() {
fmt.Println("Hello, world")
}

View File

@@ -1,7 +1,7 @@
package main
import (
"github.com/goplus/llgo/_demo/interf/foo"
"github.com/goplus/llgo/_cmptest/interf/foo"
)
func Foo() any {

14
_cmptest/iodemo/io.go Normal file
View File

@@ -0,0 +1,14 @@
package main
import (
"io"
"os"
)
func f(w io.Writer) {
w.Write([]byte("Hello, world\n"))
}
func main() {
f(os.Stdout)
}

18
_cmptest/osdemo/osd.go Normal file
View File

@@ -0,0 +1,18 @@
package main
import (
"os"
)
func main() {
home, _ := os.UserHomeDir()
println("home:", home)
cfgdir, _ := os.UserConfigDir()
println("cfgdir:", cfgdir)
cache, _ := os.UserCacheDir()
println("cachedir:", cache)
os.Stdout.Write([]byte("Hello, World\n"))
}

View File

@@ -0,0 +1,13 @@
package main
import "reflect"
func main() {
tyIntSlice := reflect.SliceOf(reflect.TypeOf(0))
v := reflect.Zero(tyIntSlice)
v = reflect.Append(v, reflect.ValueOf(1), reflect.ValueOf(2), reflect.ValueOf(3))
for i, n := 0, v.Len(); i < n; i++ {
item := v.Index(i)
println(item.Int())
}
}

14
_cmptest/rtype/rtype.go Normal file
View File

@@ -0,0 +1,14 @@
package main
import "reflect"
func main() {
tyIntSlice := reflect.SliceOf(reflect.TypeOf(0))
println(tyIntSlice.String())
v := reflect.Zero(tyIntSlice)
println(v.Len())
v = reflect.ValueOf(100)
println(v.Int())
}

23
_cmptest/sortdemo/sort.go Normal file
View File

@@ -0,0 +1,23 @@
package main
import "sort"
func main() {
vals := []int{32, 58, 25, 92, 45, 78}
sort.Ints(vals)
for _, v := range vals {
println(v)
}
texts := []string{"apple", "banana", "cherry", "date", "elderberry", "fig"}
sort.Slice(texts, func(i, j int) bool {
leni, lenj := len(texts[i]), len(texts[j])
if leni != lenj {
return leni < lenj
}
return texts[i] < texts[j]
})
for _, v := range texts {
println(v)
}
}

View File

@@ -0,0 +1,7 @@
package main
import "strconv"
func main() {
println(strconv.Itoa(-123))
}

View File

@@ -0,0 +1,11 @@
package main
import "syscall"
func main() {
wd, err := syscall.Getwd()
if err != nil {
panic(err)
}
println("cwd:", wd)
}

View File

@@ -0,0 +1,8 @@
package main
import "time"
func main() {
t := time.Date(2018, time.January, 1, 2, 3, 4, 5, time.UTC)
println(t.String())
}

24
_demo/catomic/atomic.go Normal file
View File

@@ -0,0 +1,24 @@
package main
import (
"github.com/goplus/llgo/c/sync/atomic"
)
func main() {
var v int64
atomic.Store(&v, 100)
println("store:", atomic.Load(&v))
ret := atomic.Add(&v, 1)
println("ret:", ret, "v:", v)
ret, _ = atomic.CompareAndExchange(&v, 100, 102)
println("ret:", ret, "vs 100, v:", v)
ret, _ = atomic.CompareAndExchange(&v, 101, 102)
println("ret:", ret, "vs 101, v:", v)
ret = atomic.Sub(&v, 1)
println("ret:", ret, "v:", v)
}

49
_demo/cchan/cchan.go Normal file
View File

@@ -0,0 +1,49 @@
package main
import (
"unsafe"
"github.com/goplus/llgo/internal/runtime"
)
const (
eltSize = int(unsafe.Sizeof(0))
)
func doChan(cap int) {
c := runtime.NewChan(eltSize, cap)
go func() {
v := 100
runtime.ChanSend(c, unsafe.Pointer(&v), eltSize)
}()
var ret int
runtime.ChanRecv(c, unsafe.Pointer(&ret), eltSize)
println(ret)
}
func main() {
doChan(10)
doChan(0)
c := runtime.NewChan(eltSize, 3)
v := 1
runtime.ChanSend(c, unsafe.Pointer(&v), eltSize)
v = 2
runtime.ChanSend(c, unsafe.Pointer(&v), eltSize)
v = 3
runtime.ChanSend(c, unsafe.Pointer(&v), eltSize)
runtime.ChanClose(c)
v = 10
if runtime.ChanTrySend(c, unsafe.Pointer(&v), eltSize) {
println("error: chan send to closed chan")
}
for {
if ok := runtime.ChanRecv(c, unsafe.Pointer(&v), eltSize); !ok {
break
}
println(v)
}
}

9
_demo/complex/cmplx.go Normal file
View File

@@ -0,0 +1,9 @@
package main
import (
"math/cmplx"
)
func main() {
println("abs(3+4i):", cmplx.Abs(3+4i))
}

38
_demo/cppintf/cppintf.go Normal file
View File

@@ -0,0 +1,38 @@
package main
import (
"github.com/goplus/llgo/_demo/cppintf/foo"
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/math"
)
type Bar struct {
foo.Callback
a c.Int
}
func NewBar(a c.Int) *Bar {
return &Bar{
Callback: foo.Callback{
Vptr: &foo.CallbackVtbl{
Val: c.Func((*Bar).getA),
Calc: c.Func((*Bar).sqrt),
},
},
a: a,
}
}
func (p *Bar) getA() c.Int {
return p.a
}
func (p *Bar) sqrt(v float64) float64 {
return math.Sqrt(v)
}
func main() {
bar := NewBar(1)
foo.F(&bar.Callback)
foo.G(&bar.Callback)
}

View File

@@ -0,0 +1,15 @@
#include <stdio.h>
#define interface struct
interface ICallback {
virtual int val() = 0;
virtual double calc(double v) = 0;
};
extern "C" void f(ICallback* cb) {
printf("val: %d\ncalc(2): %lf\n", cb->val(), cb->calc(2));
}
void g(ICallback* cb) {
f(cb);
}

25
_demo/cppintf/foo/foo.go Normal file
View File

@@ -0,0 +1,25 @@
package foo
import (
"unsafe"
)
const (
LLGoFiles = "bar/bar.cpp"
LLGoPackage = "link"
)
type Callback struct {
Vptr *CallbackVtbl
}
type CallbackVtbl struct {
Val unsafe.Pointer
Calc unsafe.Pointer
}
//go:linkname F C.f
func F(cb *Callback)
//go:linkname G C._Z1gP9ICallback
func G(cb *Callback)

Binary file not shown.

View File

@@ -0,0 +1,50 @@
package main
import (
"unsafe"
"github.com/goplus/llgo/_demo/cppmintf/foo"
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/math"
)
type Bar struct {
foo.Callback
a c.Int
}
func NewBar(a c.Int) *Bar {
return &Bar{
Callback: foo.Callback{
ICalc: foo.ICalc{
Vptr: &foo.ICalcVtbl{
Calc: c.Func((*Bar).sqrt),
},
},
IVal: foo.IVal{
Vptr: &foo.IValVtbl{
Val: c.Func(bar_IVal_getA),
},
},
},
a: a,
}
}
func (p *Bar) getA() c.Int {
return p.a
}
func bar_IVal_getA(this c.Pointer) c.Int {
const delta = -int(unsafe.Offsetof(foo.Callback{}.IVal))
return (*Bar)(c.Advance(this, delta)).getA()
}
func (p *Bar) sqrt(v float64) float64 {
return math.Sqrt(v)
}
func main() {
bar := NewBar(1)
foo.F(&bar.Callback)
}

View File

@@ -0,0 +1,17 @@
#include <stdio.h>
#define interface struct
interface ICalc {
virtual double calc(double v) = 0;
};
interface IVal {
virtual int val() = 0;
};
class Callback : public ICalc, public IVal {
};
extern "C" void f(Callback* cb) {
printf("val: %d\ncalc(2): %lf\n", cb->val(), cb->calc(2));
}

42
_demo/cppmintf/foo/foo.go Normal file
View File

@@ -0,0 +1,42 @@
package foo
import (
"unsafe"
)
const (
LLGoFiles = "bar/bar.cpp"
LLGoPackage = "link"
)
// -----------------------------------------------------------------------------
type ICalc struct {
Vptr *ICalcVtbl
}
type ICalcVtbl struct {
Calc unsafe.Pointer
}
// -----------------------------------------------------------------------------
type IVal struct {
Vptr *IValVtbl
}
type IValVtbl struct {
Val unsafe.Pointer
}
// -----------------------------------------------------------------------------
type Callback struct {
ICalc
IVal
}
//go:linkname F C.f
func F(cb *Callback)
// -----------------------------------------------------------------------------

Binary file not shown.

12
_demo/ctime/time.go Normal file
View File

@@ -0,0 +1,12 @@
package main
import "github.com/goplus/llgo/c/time"
func main() {
var tv time.Timespec
time.ClockGettime(time.CLOCK_REALTIME, &tv)
println("REALTIME sec:", tv.Sec, "nsec:", tv.Nsec)
time.ClockGettime(time.CLOCK_MONOTONIC, &tv)
println("MONOTONIC sec:", tv.Sec, "nsec:", tv.Nsec)
}

11
_demo/getcwd/getcwd.go Normal file
View File

@@ -0,0 +1,11 @@
package main
import (
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/os"
)
func main() {
wd := os.Getcwd(c.Alloca(os.PATH_MAX), os.PATH_MAX)
c.Printf(c.Str("cwd: %s\n"), wd)
}

View File

@@ -0,0 +1,12 @@
package main
func main() {
done := false
go func() {
println("Hello, goroutine")
done = true
}()
for !done {
print(".")
}
}

7
_demo/gotime/time.go Normal file
View File

@@ -0,0 +1,7 @@
package main
import "time"
func main() {
println(time.Now().String())
}

11
_demo/math/math.go Normal file
View File

@@ -0,0 +1,11 @@
package main
import (
"math"
)
func main() {
println(math.Sqrt(2))
println(math.Abs(-1.2))
println(math.Ldexp(1.2, 3))
}

15
_demo/rand/rand.go Normal file
View File

@@ -0,0 +1,15 @@
package main
import (
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/math/rand"
)
func main() {
var s c.Uint = 6
rand.Srand(s)
rr := rand.RandR(&s)
r := rand.Rand()
println("r:", r)
println("rr:", rr)
}

16
_demo/setjmp/setjmp.go Normal file
View File

@@ -0,0 +1,16 @@
package main
import (
"github.com/goplus/llgo/c/setjmp"
)
func main() {
var jb setjmp.SigjmpBuf
switch ret := setjmp.Sigsetjmp(&jb, 0); ret {
case 0:
println("Hello, setjmp!")
setjmp.Siglongjmp(&jb, 1)
default:
println("exception:", ret)
}
}

25
_demo/thread/thd.go Normal file
View File

@@ -0,0 +1,25 @@
package main
import (
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/pthread"
)
var key pthread.Key
func main() {
key.Create(nil)
key.Set(c.Pointer(c.Str("main value\n")))
var thd pthread.Thread
pthread.Create(&thd, nil, func(arg c.Pointer) c.Pointer {
key.Set(c.Pointer(c.Str("thread value\n")))
c.Printf(c.Str("Hello, thread\nTLS: %s"), key.Get())
return c.Pointer(c.Str("Back to main\n"))
}, nil)
var retval c.Pointer
pthread.Join(thd, &retval)
c.Printf(c.Str("%sTLS: %s"), retval, key.Get())
}

101
_test/bdwgc.go Normal file
View File

@@ -0,0 +1,101 @@
package main
import (
"unsafe"
"github.com/goplus/llgo/_test/testing"
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/bdwgc"
)
// ------ Test malloc ------
func TestMalloc(t *testing.T) {
pn := (*int)(bdwgc.Malloc(unsafe.Sizeof(int(0))))
*pn = 1 << 30
c.Printf(c.Str("value: %d, %x, %p, %p\n"), *pn, *pn, pn, &pn)
pl := (*int64)(bdwgc.Realloc(c.Pointer(pn), unsafe.Sizeof(int64(0))))
*pl = 1 << 60
c.Printf(c.Str("value: %lld, %llx, %p, %p\n"), *pl, *pl, pl, &pl)
bdwgc.Free(c.Pointer(pl))
}
// ------ Test finalizer ------
const (
RETURN_VALUE_FREED = 1 << 31
)
var called uint = 0
func setReturnValueFreed(pobj c.Pointer, clientData c.Pointer) {
called |= RETURN_VALUE_FREED
c.Printf(c.Str("called: %x\n"), called)
}
func setLoopValueFreed(pobj c.Pointer, clientData c.Pointer) {
pmask := (*uint)(clientData)
called |= *pmask
c.Printf(c.Str("called: %x\n"), called)
}
func isCalled(mask uint) bool {
return called&mask != 0
}
func returnValue() *int {
pn := bdwgc.Malloc(unsafe.Sizeof(int(0)))
bdwgc.RegisterFinalizer(pn, setReturnValueFreed, nil, nil, nil)
return (*int)(pn)
}
func callFunc() {
pn := returnValue()
*pn = 1 << 30
c.Printf(c.Str("value: %d, %x, %p, %p\n"), *pn, *pn, pn, &pn)
bdwgc.Gcollect()
check(!isCalled(RETURN_VALUE_FREED), c.Str("finalizer should not be called"))
}
func loop() {
for i := 0; i < 5; i++ {
p := bdwgc.Malloc(unsafe.Sizeof(int(0)))
pn := (*int)(p)
*pn = i
c.Printf(c.Str("value: %d, %x, %p, %p\n"), *pn, *pn, pn, &pn)
pflag := (*uint)(c.Malloc(unsafe.Sizeof(uint(0))))
*pflag = 1 << i
bdwgc.RegisterFinalizer(p, setLoopValueFreed, c.Pointer(pflag), nil, nil)
bdwgc.Gcollect()
check(!isCalled(1<<i), c.Str("finalizer should not be called"))
for j := 0; j < i; j++ {
check(isCalled(1<<j), c.Str("finalizers of previous objects should be called"))
}
}
}
// Clear stack to avoid reference
func clearStack() {
p := c.Alloca(128)
c.Memset(p, 0, 128)
}
func check(b bool, msg *c.Char) {
if !b {
c.Printf(c.Str("check failed: %s\n"), msg)
panic("check failed")
}
}
func TestFinalizer(t *testing.T) {
bdwgc.Init()
callFunc()
clearStack()
bdwgc.Gcollect()
check(isCalled(RETURN_VALUE_FREED), c.Str("finalizer should be called"))
loop()
}

31
_test/main.go Normal file
View File

@@ -0,0 +1,31 @@
package main
import (
"github.com/goplus/llgo/_test/testing"
"github.com/goplus/llgo/c"
)
type TestCase struct {
Name string
F func(*testing.T)
}
func main() {
tests := []TestCase{
{"TestMalloc", TestMalloc},
{"TestFinalizer", TestFinalizer},
}
if c.Argc == 1 {
for _, test := range tests {
c.Printf(c.Str("%s\n"), c.AllocaCStr(test.Name))
}
return
}
c.Fprintf(c.Stderr, c.Str("arg: %s\n"), c.Index(c.Argv, 1))
idx := int(c.Atoi(c.Index(c.Argv, 1)))
if idx < 0 || idx >= len(tests) {
c.Printf(c.Str("invalid test index %d"), idx)
panic("invalid test index")
}
tests[idx].F(nil)
}

4
_test/testing/testing.go Normal file
View File

@@ -0,0 +1,4 @@
package testing
type T struct {
}

103
c/bdwgc/bdwgc.go Normal file
View File

@@ -0,0 +1,103 @@
/*
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package bdwgc
import (
_ "unsafe"
"github.com/goplus/llgo/c"
)
const (
LLGoPackage = "link: $(pkg-config --libs bdw-gc); -lgc"
)
// -----------------------------------------------------------------------------
//go:linkname Init C.GC_init
func Init()
//go:linkname Malloc C.GC_malloc
func Malloc(size uintptr) c.Pointer
//go:linkname Realloc C.GC_realloc
func Realloc(ptr c.Pointer, size uintptr) c.Pointer
//go:linkname Free C.GC_free
func Free(ptr c.Pointer)
// -----------------------------------------------------------------------------
//go:linkname RegisterFinalizer C.GC_register_finalizer
func RegisterFinalizer(
obj c.Pointer,
fn func(c.Pointer, c.Pointer), cd c.Pointer,
oldFn *func(c.Pointer, c.Pointer), oldCd *c.Pointer)
//go:linkname RegisterFinalizerNoOrder C.GC_register_finalizer_no_order
func RegisterFinalizerNoOrder(
obj c.Pointer,
fn func(c.Pointer, c.Pointer), cd c.Pointer,
oldFn *func(c.Pointer, c.Pointer), oldCd *c.Pointer)
//go:linkname RegisterFinalizerIgnoreSelf C.GC_register_finalizer_ignore_self
func RegisterFinalizerIgnoreSelf(
obj c.Pointer,
fn func(c.Pointer, c.Pointer), cd c.Pointer,
oldFn *func(c.Pointer, c.Pointer), oldCd *c.Pointer)
//go:linkname RegisterFinalizerUnreachable C.GC_register_finalizer_unreachable
func RegisterFinalizerUnreachable(
obj c.Pointer,
fn func(c.Pointer, c.Pointer), cd c.Pointer,
oldFn *func(c.Pointer, c.Pointer), oldCd *c.Pointer)
// -----------------------------------------------------------------------------
//go:linkname Enable C.GC_enable
func Enable()
//go:linkname Disable C.GC_disable
func Disable()
//go:linkname IsDisabled C.GC_is_disabled
func IsDisabled() c.Int
//go:linkname Gcollect C.GC_gcollect
func Gcollect()
//go:linkname GetMemoryUse C.GC_get_memory_use
func GetMemoryUse() uintptr
// -----------------------------------------------------------------------------
//go:linkname EnableIncremental C.GC_enable_incremental
func EnableIncremental()
//go:linkname IsIncrementalMode C.GC_is_incremental_mode
func IsIncrementalMode() c.Int
//go:linkname IncrementalProtectionNeeds C.GC_incremental_protection_needs
func IncrementalProtectionNeeds() c.Int
//go:linkname StartIncrementalCollection C.GC_start_incremental_collection
func StartIncrementalCollection()
//go:linkname CollectALittle C.GC_collect_a_little
func CollectALittle()
// -----------------------------------------------------------------------------

BIN
c/bdwgc/llgo_autogen.lla Normal file

Binary file not shown.

17
c/bitcast/_cast/cast.c Normal file
View File

@@ -0,0 +1,17 @@
typedef union {
double d;
float f;
long v;
} castUnion;
double llgoToFloat64(long v) {
castUnion k;
k.v = v;
return k.d;
}
float llgoToFloat32(long v) {
castUnion k;
k.v = v;
return k.f;
}

30
c/bitcast/bitcast.go Normal file
View File

@@ -0,0 +1,30 @@
/*
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package bitcast
import _ "unsafe"
const (
LLGoFiles = "_cast/cast.c"
LLGoPackage = "link"
)
//go:linkname ToFloat64 C.llgoToFloat64
func ToFloat64(v uintptr) float64
//go:linkname ToFloat32 C.llgoToFloat32
func ToFloat32(v uintptr) float32

BIN
c/bitcast/llgo_autogen.lla Normal file

Binary file not shown.

144
c/c.go
View File

@@ -17,6 +17,9 @@
package c
// typedef unsigned int uint;
// typedef unsigned long ulong;
// typedef unsigned long long ulonglong;
// typedef long long longlong;
import "C"
import "unsafe"
@@ -25,17 +28,22 @@ const (
)
type (
Char = int8
Int = C.int
Uint = C.uint
Long = int32
Ulong = uint32
LongLong = int64
UlongLong = uint64
Float = float32
Double = float64
Pointer = unsafe.Pointer
FilePtr = unsafe.Pointer
Char = int8
Float = float32
Double = float64
Pointer = unsafe.Pointer
FilePtr = unsafe.Pointer
)
type (
Int C.int
Uint C.uint
Long C.long
Ulong C.ulong
LongLong C.longlong
UlongLong C.ulonglong
)
type integer interface {
@@ -45,8 +53,11 @@ type integer interface {
//go:linkname Str llgo.cstr
func Str(string) *Char
//go:linkname Func llgo.funcAddr
func Func(any) Pointer
// llgo:link Advance llgo.advance
func Advance[PtrT any](ptr PtrT, offset int) PtrT { return ptr }
func Advance[PtrT any, I integer](ptr PtrT, offset I) PtrT { return ptr }
// llgo:link Index llgo.index
func Index[T any, I integer](ptr *T, offset I) T { return *ptr }
@@ -57,27 +68,107 @@ func Alloca(size uintptr) Pointer
//go:linkname AllocaCStr llgo.allocaCStr
func AllocaCStr(s string) *Char
//go:linkname Unreachable llgo.unreachable
func Unreachable()
//go:linkname Malloc C.malloc
func Malloc(size uintptr) Pointer
//go:linkname Free C.free
func Free(ptr Pointer)
//go:linkname Memcpy C.memcpy
func Memcpy(dst, src Pointer, n uintptr) Pointer
//go:linkname Memmove C.memmove
func Memmove(dst, src Pointer, n uintptr) Pointer
//go:linkname Memset C.memset
func Memset(s Pointer, c Int, n uintptr) Pointer
//go:linkname Memchr C.memchr
func Memchr(s Pointer, c Int, n uintptr) Pointer
//go:linkname Memcmp C.memcmp
func Memcmp(s1, s2 Pointer, n uintptr) Int
// -----------------------------------------------------------------------------
//go:linkname Strlen C.strlen
func Strlen(s *Char) uintptr
//go:linkname Strcpy C.strcpy
func Strcpy(dst, src *Char) *Char
//go:linkname Strncpy C.strncpy
func Strncpy(dst, src *Char, n uintptr) *Char
//go:linkname Strcat C.strcat
func Strcat(dst, src *Char) *Char
//go:linkname Strncat C.strncat
func Strncat(dst, src *Char, n uintptr) *Char
//go:linkname Strcmp C.strcmp
func Strcmp(s1, s2 *Char) Int
//go:linkname Strncmp C.strncmp
func Strncmp(s1, s2 *Char, n uintptr) Int
//go:linkname Strchr C.strchr
func Strchr(s *Char, c Int) *Char
//go:linkname Strrchr C.strrchr
func Strrchr(s *Char, c Int) *Char
//go:linkname Strstr C.strstr
func Strstr(s1, s2 *Char) *Char
//go:linkname Strdup C.strdup
func Strdup(s *Char) *Char
//go:linkname Strndup C.strndup
func Strndup(s *Char, n uintptr) *Char
//go:linkname Strtok C.strtok
func Strtok(s, delim *Char) *Char
//go:linkname Strerror C.strerror
func Strerror(errnum Int) *Char
//go:linkname Sprintf C.sprintf
func Sprintf(s *Char, format *Char, __llgo_va_list ...any) Int
//go:linkname Snprintf C.snprintf
func Snprintf(s *Char, n uintptr, format *Char, __llgo_va_list ...any) Int
//go:linkname Vsnprintf C.vsnprintf
func Vsnprintf(s *Char, n uintptr, format *Char, ap Pointer) Int
// -----------------------------------------------------------------------------
// GoString converts a C string to a Go string.
// TODO(xsw): any => int
//
//go:linkname GoString llgo.string
func GoString(cstr *Char, __llgo_va_list /* n */ ...any) string
//go:linkname GoStringData llgo.stringData
func GoStringData(string) *Char
//go:linkname GoDeferData llgo.deferData
func GoDeferData() Pointer
// -----------------------------------------------------------------------------
//go:linkname Remove C.remove
func Remove(path *Char) Int
//go:linkname AllocaSigjmpBuf llgo.sigjmpbuf
func AllocaSigjmpBuf() Pointer
//go:linkname Sigsetjmp llgo.sigsetjmp
func Sigsetjmp(jb Pointer, savemask Int) Int
//go:linkname Siglongjmp llgo.siglongjmp
func Siglongjmp(jb Pointer, retval Int)
//go:linkname Unreachable llgo.unreachable
func Unreachable()
// -----------------------------------------------------------------------------
@@ -94,14 +185,10 @@ func Qsort(base Pointer, count, elem uintptr, compar func(a, b Pointer) Int)
// -----------------------------------------------------------------------------
//go:linkname Stdin __stdinp
var Stdin FilePtr
//go:linkname Atoi C.atoi
func Atoi(s *Char) Int
//go:linkname Stdout __stdoutp
var Stdout FilePtr
//go:linkname Stderr __stderrp
var Stderr FilePtr
// -----------------------------------------------------------------------------
//go:linkname Printf C.printf
func Printf(format *Char, __llgo_va_list ...any) Int
@@ -115,11 +202,20 @@ func Fwrite(data Pointer, size, count uintptr, fp FilePtr) uintptr
//go:linkname Fputc C.fputc
func Fputc(c Int, fp FilePtr) Int
//go:linkname Fputs C.fputs
func Fputs(s *Char, fp FilePtr) Int
//go:linkname Fflush C.fflush
func Fflush(fp FilePtr) Int
// -----------------------------------------------------------------------------
//go:linkname Time C.time
func Time(*int32) int32
//go:linkname Usleep C.usleep
func Usleep(useconds Uint) Int
// -----------------------------------------------------------------------------
type Option struct {

31
c/c_default.go Normal file
View File

@@ -0,0 +1,31 @@
//go:build !linux
// +build !linux
/*
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package c
import _ "unsafe"
//go:linkname Stdin __stdinp
var Stdin FilePtr
//go:linkname Stdout __stdoutp
var Stdout FilePtr
//go:linkname Stderr __stderrp
var Stderr FilePtr

31
c/c_linux.go Normal file
View File

@@ -0,0 +1,31 @@
//go:build linux
// +build linux
/*
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package c
import _ "unsafe"
//go:linkname Stdin stdin
var Stdin FilePtr
//go:linkname Stdout stdout
var Stdout FilePtr
//go:linkname Stderr stderr
var Stderr FilePtr

View File

@@ -1,22 +1,18 @@
LLGo wrapper of DaveGamble/cJSON
=====
[![Build Status](https://github.com/goplus/cjson/actions/workflows/go.yml/badge.svg)](https://github.com/goplus/cjson/actions/workflows/go.yml)
[![GitHub release](https://img.shields.io/github/v/tag/goplus/cjson.svg?label=release)](https://github.com/goplus/cjson/releases)
[![GoDoc](https://pkg.go.dev/badge/github.com/goplus/cjson.svg)](https://pkg.go.dev/github.com/goplus/cjson)
[![Compiler](https://img.shields.io/badge/compiler-llgo-darkgreen.svg)](https://github.com/goplus/llgo)
[![Language](https://img.shields.io/badge/language-Go+-blue.svg)](https://github.com/goplus/gop)
## How to install
### on macOS (Homebrew)
```sh
git clone https://github.com/goplus/cjson.git
cd cjson
git submodule init
git submodule update
mkdir build.dir
cd build.dir
cmake ../cJSON
sudo make install
brew install cjson
```
### on Linux (Debian/Ubuntu)
```sh
apt-get install -y libcjson-dev
```
## Demos

View File

@@ -23,7 +23,7 @@ import (
)
const (
LLGoPackage = "link: cjson"
LLGoPackage = "link: $(pkg-config --libs libcjson); -lcjson"
)
// llgo:type C

View File

@@ -0,0 +1,49 @@
package main
import (
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/clang"
)
func visit(cursor, parent clang.Cursor, clientData c.Pointer) clang.ChildVisitResult {
depth := *(*c.Uint)(clientData)
printAST(cursor, depth+1)
return clang.ChildVisit_Continue
}
func printAST(cursor clang.Cursor, depth c.Uint) {
cursorKind := cursor.Kind.String()
cursorSpelling := cursor.String()
for i := c.Uint(0); i < depth; i++ {
c.Fputs(c.Str(" "), c.Stdout)
}
c.Printf(c.Str("%s: %s\n"), cursorKind.CStr(), cursorSpelling.CStr())
cursorKind.Dispose()
cursorSpelling.Dispose()
clang.VisitChildren(cursor, visit, c.Pointer(&depth))
}
func main() {
index := clang.CreateIndex(0, 0)
unit := index.ParseTranslationUnit(
c.Str("todo"),
nil, 0,
nil, 0,
clang.TranslationUnit_None,
)
if unit == nil {
println("Unable to parse translation unit. Quitting.")
c.Exit(1)
}
cursor := unit.Cursor()
printAST(cursor, 0)
unit.Dispose()
index.Dispose()
}

59
c/clang/basic.go Normal file
View File

@@ -0,0 +1,59 @@
/*
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package clang
import (
_ "unsafe"
"github.com/goplus/llgo/c"
)
/**
* A character string.
*
* The \c CXString type is used to return strings from the interface when
* the ownership of that string might differ from one call to the next.
* Use \c clang_getCString() to retrieve the string data and, once finished
* with the string data, call \c clang_disposeString() to free the string.
*/
type String struct {
Data c.Pointer
PrivateFlags c.Uint
}
/**
* Retrieve the character data associated with the given string.
*/
// llgo:link C.clang_getCString
func (String) CStr() *c.Char { return nil }
/**
* Free the given string.
*/
// llgo:link C.clang_disposeString
func (String) Dispose() {}
type StringSet struct {
Strings *String
Count c.Uint
}
/**
* Free the given string set.
*/
// llgo:link C.clang_disposeStringSet
func (*StringSet) Dispose() {}

266
c/clang/clang.go Normal file
View File

@@ -0,0 +1,266 @@
/*
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package clang
import (
_ "unsafe"
"github.com/goplus/llgo/c"
)
const (
LLGoPackage = "link: -L$(llvm-config --libdir) -lclang; -lclang"
)
/**
* Opaque pointer representing client data that will be passed through
* to various callbacks and visitors.
*/
type ClientData = c.Pointer
/**
* Provides the contents of a file that has not yet been saved to disk.
*
* Each CXUnsavedFile instance provides the name of a file on the
* system along with the current contents of that file that have not
* yet been saved to disk.
*/
type UnsavedFile struct {
/**
* The file whose contents have not yet been saved.
*
* This file must already exist in the file system.
*/
Filename *c.Char
/**
* A buffer containing the unsaved contents of this file.
*/
Contents *c.Char
/**
* The length of the unsaved contents of this buffer.
*/
Length c.Ulong
}
/**
* An "index" that consists of a set of translation units that would
* typically be linked together into an executable or library.
*/
type Index struct {
Unused [0]byte
}
/**
* Provides a shared context for creating translation units.
*
* It provides two options:
*
* - excludeDeclarationsFromPCH: When non-zero, allows enumeration of "local"
* declarations (when loading any new translation units). A "local" declaration
* is one that belongs in the translation unit itself and not in a precompiled
* header that was used by the translation unit. If zero, all declarations
* will be enumerated.
*
* Here is an example:
*
* \code
* // excludeDeclsFromPCH = 1, displayDiagnostics=1
* Idx = clang_createIndex(1, 1);
*
* // IndexTest.pch was produced with the following command:
* // "clang -x c IndexTest.h -emit-ast -o IndexTest.pch"
* TU = clang_createTranslationUnit(Idx, "IndexTest.pch");
*
* // This will load all the symbols from 'IndexTest.pch'
* clang_visitChildren(clang_getTranslationUnitCursor(TU),
* TranslationUnitVisitor, 0);
* clang_disposeTranslationUnit(TU);
*
* // This will load all the symbols from 'IndexTest.c', excluding symbols
* // from 'IndexTest.pch'.
* char *args[] = { "-Xclang", "-include-pch=IndexTest.pch" };
* TU = clang_createTranslationUnitFromSourceFile(Idx, "IndexTest.c", 2, args,
* 0, 0);
* clang_visitChildren(clang_getTranslationUnitCursor(TU),
* TranslationUnitVisitor, 0);
* clang_disposeTranslationUnit(TU);
* \endcode
*
* This process of creating the 'pch', loading it separately, and using it (via
* -include-pch) allows 'excludeDeclsFromPCH' to remove redundant callbacks
* (which gives the indexer the same performance benefit as the compiler).
*/
//go:linkname CreateIndex C.clang_createIndex
func CreateIndex(excludeDeclarationsFromPCH, displayDiagnostics c.Int) *Index
/**
* Destroy the given index.
*
* The index must not be destroyed until all of the translation units created
* within that index have been destroyed.
*/
// llgo:link (*Index).Dispose C.clang_disposeIndex
func (*Index) Dispose() {}
/**
* Flags that control the creation of translation units.
*
* The enumerators in this enumeration type are meant to be bitwise
* ORed together to specify which options should be used when
* constructing the translation unit.
*/
const (
TranslationUnit_None = 0x0
)
/**
* Same as \c clang_parseTranslationUnit2, but returns
* the \c CXTranslationUnit instead of an error code. In case of an error this
* routine returns a \c NULL \c CXTranslationUnit, without further detailed
* error codes.
*/
// llgo:link (*Index).ParseTranslationUnit C.clang_parseTranslationUnit
func (*Index) ParseTranslationUnit(
sourceFilename *c.Char, commandLineArgs **c.Char, numCommandLineArgs c.Int,
unsavedFiles *UnsavedFile, numUnsavedFiles c.Uint, options c.Uint) *TranslationUnit {
return nil
}
/**
* A single translation unit, which resides in an index.
*/
type TranslationUnit struct {
Unused [0]byte
}
/**
* Destroy the specified CXTranslationUnit object.
*/
// llgo:linke (*TranslationUnit).Dispose C.clang_disposeTranslationUnit
func (*TranslationUnit) Dispose() {}
/**
* Retrieve the cursor that represents the given translation unit.
*
* The translation unit cursor can be used to start traversing the
* various declarations within the given translation unit.
*/
// llgo:link (*TranslationUnit).Cursor C.clang_getTranslationUnitCursor
func (*TranslationUnit) Cursor() (ret Cursor) {
return
}
/**
* Describes the kind of entity that a cursor refers to.
*/
type CursorKind c.Int
/* for debug/testing */
// llgo:link (CursorKind).String C.clang_getCursorKindSpelling
func (CursorKind) String() (ret String) {
return
}
/**
* A cursor representing some element in the abstract syntax tree for
* a translation unit.
*
* The cursor abstraction unifies the different kinds of entities in a
* program--declaration, statements, expressions, references to declarations,
* etc.--under a single "cursor" abstraction with a common set of operations.
* Common operation for a cursor include: getting the physical location in
* a source file where the cursor points, getting the name associated with a
* cursor, and retrieving cursors for any child nodes of a particular cursor.
*
* Cursors can be produced in two specific ways.
* clang_getTranslationUnitCursor() produces a cursor for a translation unit,
* from which one can use clang_visitChildren() to explore the rest of the
* translation unit. clang_getCursor() maps from a physical source location
* to the entity that resides at that location, allowing one to map from the
* source code into the AST.
*/
type Cursor struct {
Kind CursorKind
Xdata c.Int
Data [3]c.Pointer
}
/**
* Retrieve a name for the entity referenced by this cursor.
*/
// llgo:link C.clang_getCursorSpelling
func (Cursor) String() (ret String) {
return
}
/**
* Describes how the traversal of the children of a particular
* cursor should proceed after visiting a particular child cursor.
*
* A value of this enumeration type should be returned by each
* \c CXCursorVisitor to indicate how clang_visitChildren() proceed.
*/
type ChildVisitResult c.Int
const (
/**
* Terminates the cursor traversal.
*/
ChildVisit_Break ChildVisitResult = iota
/**
* Continues the cursor traversal with the next sibling of
* the cursor just visited, without visiting its children.
*/
ChildVisit_Continue
/**
* Recursively traverse the children of this cursor, using
* the same visitor and client data.
*/
ChildVisit_Recurse
)
/**
* Visit the children of a particular cursor.
*
* This function visits all the direct children of the given cursor,
* invoking the given \p visitor function with the cursors of each
* visited child. The traversal may be recursive, if the visitor returns
* \c CXChildVisit_Recurse. The traversal may also be ended prematurely, if
* the visitor returns \c CXChildVisit_Break.
*
* \param parent the cursor whose child may be visited. All kinds of
* cursors can be visited, including invalid cursors (which, by
* definition, have no children).
*
* \param visitor the visitor function that will be invoked for each
* child of \p parent.
*
* \param client_data pointer data supplied by the client, which will
* be passed to the visitor each time it is invoked.
*
* \returns a non-zero value if the traversal was terminated
* prematurely by the visitor returning \c CXChildVisit_Break.
*/
//go:linkname VisitChildren C.clang_visitChildren
func VisitChildren(
cusor Cursor,
visitor func(cursor, parent Cursor, clientData ClientData) ChildVisitResult,
clientData ClientData) c.Uint {
return 0
}

BIN
c/clang/llgo_autogen.lla Normal file

Binary file not shown.

10
c/llama2/README.md Normal file
View File

@@ -0,0 +1,10 @@
LLGo wrapper of karpathy/llama2.c
=====
## How to update source to llgo
```
git submodule init
git submodule update
cp llama2.c/run.c llama2/run.c
```

View File

@@ -23,7 +23,8 @@ import (
)
const (
LLGoPackage = "link"
LLGoFiles = "llama2/llama2.c"
LLGoPackage = "link: -lm"
)
// -----------------------------------------------------------------------------

2
c/llama2/llama2/llama2.c Normal file
View File

@@ -0,0 +1,2 @@
#define TESTING
#include "./run.c"

View File

@@ -1,2 +1,973 @@
#define TESTING
#include "../llama2.c/run.c"
/* Inference for Llama-2 Transformer model in pure C */
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <time.h>
#include <math.h>
#include <string.h>
#include <fcntl.h>
#if defined _WIN32
#include "win.h"
#else
#include <unistd.h>
#include <sys/mman.h>
#endif
// ----------------------------------------------------------------------------
// Transformer model
typedef struct {
int dim; // transformer dimension
int hidden_dim; // for ffn layers
int n_layers; // number of layers
int n_heads; // number of query heads
int n_kv_heads; // number of key/value heads (can be < query heads because of multiquery)
int vocab_size; // vocabulary size, usually 256 (byte-level)
int seq_len; // max sequence length
} Config;
typedef struct {
// token embedding table
float* token_embedding_table; // (vocab_size, dim)
// weights for rmsnorms
float* rms_att_weight; // (layer, dim) rmsnorm weights
float* rms_ffn_weight; // (layer, dim)
// weights for matmuls. note dim == n_heads * head_size
float* wq; // (layer, dim, n_heads * head_size)
float* wk; // (layer, dim, n_kv_heads * head_size)
float* wv; // (layer, dim, n_kv_heads * head_size)
float* wo; // (layer, n_heads * head_size, dim)
// weights for ffn
float* w1; // (layer, hidden_dim, dim)
float* w2; // (layer, dim, hidden_dim)
float* w3; // (layer, hidden_dim, dim)
// final rmsnorm
float* rms_final_weight; // (dim,)
// (optional) classifier weights for the logits, on the last layer
float* wcls;
} TransformerWeights;
typedef struct {
// current wave of activations
float *x; // activation at current time stamp (dim,)
float *xb; // same, but inside a residual branch (dim,)
float *xb2; // an additional buffer just for convenience (dim,)
float *hb; // buffer for hidden dimension in the ffn (hidden_dim,)
float *hb2; // buffer for hidden dimension in the ffn (hidden_dim,)
float *q; // query (dim,)
float *k; // key (dim,)
float *v; // value (dim,)
float *att; // buffer for scores/attention values (n_heads, seq_len)
float *logits; // output logits
// kv cache
float* key_cache; // (layer, seq_len, dim)
float* value_cache; // (layer, seq_len, dim)
} RunState;
typedef struct {
Config config; // the hyperparameters of the architecture (the blueprint)
TransformerWeights weights; // the weights of the model
RunState state; // buffers for the "wave" of activations in the forward pass
// some more state needed to properly clean up the memory mapping (sigh)
int fd; // file descriptor for memory mapping
float* data; // memory mapped data pointer
ssize_t file_size; // size of the checkpoint file in bytes
} Transformer;
void malloc_run_state(RunState* s, Config* p) {
// we calloc instead of malloc to keep valgrind happy
int kv_dim = (p->dim * p->n_kv_heads) / p->n_heads;
s->x = calloc(p->dim, sizeof(float));
s->xb = calloc(p->dim, sizeof(float));
s->xb2 = calloc(p->dim, sizeof(float));
s->hb = calloc(p->hidden_dim, sizeof(float));
s->hb2 = calloc(p->hidden_dim, sizeof(float));
s->q = calloc(p->dim, sizeof(float));
s->key_cache = calloc(p->n_layers * p->seq_len * kv_dim, sizeof(float));
s->value_cache = calloc(p->n_layers * p->seq_len * kv_dim, sizeof(float));
s->att = calloc(p->n_heads * p->seq_len, sizeof(float));
s->logits = calloc(p->vocab_size, sizeof(float));
// ensure all mallocs went fine
if (!s->x || !s->xb || !s->xb2 || !s->hb || !s->hb2 || !s->q
|| !s->key_cache || !s->value_cache || !s->att || !s->logits) {
fprintf(stderr, "malloc failed!\n");
exit(EXIT_FAILURE);
}
}
void free_run_state(RunState* s) {
free(s->x);
free(s->xb);
free(s->xb2);
free(s->hb);
free(s->hb2);
free(s->q);
free(s->att);
free(s->logits);
free(s->key_cache);
free(s->value_cache);
}
void memory_map_weights(TransformerWeights *w, Config* p, float* ptr, int shared_weights) {
int head_size = p->dim / p->n_heads;
// make sure the multiplications below are done in 64bit to fit the parameter counts of 13B+ models
unsigned long long n_layers = p->n_layers;
w->token_embedding_table = ptr;
ptr += p->vocab_size * p->dim;
w->rms_att_weight = ptr;
ptr += n_layers * p->dim;
w->wq = ptr;
ptr += n_layers * p->dim * (p->n_heads * head_size);
w->wk = ptr;
ptr += n_layers * p->dim * (p->n_kv_heads * head_size);
w->wv = ptr;
ptr += n_layers * p->dim * (p->n_kv_heads * head_size);
w->wo = ptr;
ptr += n_layers * (p->n_heads * head_size) * p->dim;
w->rms_ffn_weight = ptr;
ptr += n_layers * p->dim;
w->w1 = ptr;
ptr += n_layers * p->dim * p->hidden_dim;
w->w2 = ptr;
ptr += n_layers * p->hidden_dim * p->dim;
w->w3 = ptr;
ptr += n_layers * p->dim * p->hidden_dim;
w->rms_final_weight = ptr;
ptr += p->dim;
ptr += p->seq_len * head_size / 2; // skip what used to be freq_cis_real (for RoPE)
ptr += p->seq_len * head_size / 2; // skip what used to be freq_cis_imag (for RoPE)
w->wcls = shared_weights ? w->token_embedding_table : ptr;
}
void read_checkpoint(char* checkpoint, Config* config, TransformerWeights* weights,
int* fd, float** data, ssize_t* file_size) {
FILE *file = fopen(checkpoint, "rb");
if (!file) { fprintf(stderr, "Couldn't open file %s\n", checkpoint); exit(EXIT_FAILURE); }
// read in the config header
if (fread(config, sizeof(Config), 1, file) != 1) { exit(EXIT_FAILURE); }
// negative vocab size is hacky way of signaling unshared weights. bit yikes.
int shared_weights = config->vocab_size > 0 ? 1 : 0;
config->vocab_size = abs(config->vocab_size);
// figure out the file size
fseek(file, 0, SEEK_END); // move file pointer to end of file
*file_size = ftell(file); // get the file size, in bytes
fclose(file);
// memory map the Transformer weights into the data pointer
*fd = open(checkpoint, O_RDONLY); // open in read only mode
if (*fd == -1) { fprintf(stderr, "open failed!\n"); exit(EXIT_FAILURE); }
*data = mmap(NULL, *file_size, PROT_READ, MAP_PRIVATE, *fd, 0);
if (*data == MAP_FAILED) { fprintf(stderr, "mmap failed!\n"); exit(EXIT_FAILURE); }
float* weights_ptr = *data + sizeof(Config)/sizeof(float);
memory_map_weights(weights, config, weights_ptr, shared_weights);
}
void build_transformer(Transformer *t, char* checkpoint_path) {
// read in the Config and the Weights from the checkpoint
read_checkpoint(checkpoint_path, &t->config, &t->weights, &t->fd, &t->data, &t->file_size);
// allocate the RunState buffers
malloc_run_state(&t->state, &t->config);
}
void free_transformer(Transformer* t) {
// close the memory mapping
if (t->data != MAP_FAILED) { munmap(t->data, t->file_size); }
if (t->fd != -1) { close(t->fd); }
// free the RunState buffers
free_run_state(&t->state);
}
// ----------------------------------------------------------------------------
// neural net blocks; the dynamics of the Transformer
void rmsnorm(float* o, float* x, float* weight, int size) {
// calculate sum of squares
float ss = 0.0f;
for (int j = 0; j < size; j++) {
ss += x[j] * x[j];
}
ss /= size;
ss += 1e-5f;
ss = 1.0f / sqrtf(ss);
// normalize and scale
for (int j = 0; j < size; j++) {
o[j] = weight[j] * (ss * x[j]);
}
}
void softmax(float* x, int size) {
// find max value (for numerical stability)
float max_val = x[0];
for (int i = 1; i < size; i++) {
if (x[i] > max_val) {
max_val = x[i];
}
}
// exp and sum
float sum = 0.0f;
for (int i = 0; i < size; i++) {
x[i] = expf(x[i] - max_val);
sum += x[i];
}
// normalize
for (int i = 0; i < size; i++) {
x[i] /= sum;
}
}
void matmul(float* xout, float* x, float* w, int n, int d) {
// W (d,n) @ x (n,) -> xout (d,)
// by far the most amount of time is spent inside this little function
int i;
#pragma omp parallel for private(i)
for (i = 0; i < d; i++) {
float val = 0.0f;
for (int j = 0; j < n; j++) {
val += w[i * n + j] * x[j];
}
xout[i] = val;
}
}
float* forward(Transformer* transformer, int token, int pos) {
// a few convenience variables
Config* p = &transformer->config;
TransformerWeights* w = &transformer->weights;
RunState* s = &transformer->state;
float *x = s->x;
int dim = p->dim;
int kv_dim = (p->dim * p->n_kv_heads) / p->n_heads;
int kv_mul = p->n_heads / p->n_kv_heads; // integer multiplier of the kv sharing in multiquery
int hidden_dim = p->hidden_dim;
int head_size = dim / p->n_heads;
// copy the token embedding into x
float* content_row = w->token_embedding_table + token * dim;
memcpy(x, content_row, dim*sizeof(*x));
// forward all the layers
for(unsigned long long l = 0; l < p->n_layers; l++) {
// attention rmsnorm
rmsnorm(s->xb, x, w->rms_att_weight + l*dim, dim);
// key and value point to the kv cache
int loff = l * p->seq_len * kv_dim; // kv cache layer offset for convenience
s->k = s->key_cache + loff + pos * kv_dim;
s->v = s->value_cache + loff + pos * kv_dim;
// qkv matmuls for this position
matmul(s->q, s->xb, w->wq + l*dim*dim, dim, dim);
matmul(s->k, s->xb, w->wk + l*dim*kv_dim, dim, kv_dim);
matmul(s->v, s->xb, w->wv + l*dim*kv_dim, dim, kv_dim);
// RoPE relative positional encoding: complex-valued rotate q and k in each head
for (int i = 0; i < dim; i+=2) {
int head_dim = i % head_size;
float freq = 1.0f / powf(10000.0f, head_dim / (float)head_size);
float val = pos * freq;
float fcr = cosf(val);
float fci = sinf(val);
int rotn = i < kv_dim ? 2 : 1; // how many vectors? 2 = q & k, 1 = q only
for (int v = 0; v < rotn; v++) {
float* vec = v == 0 ? s->q : s->k; // the vector to rotate (query or key)
float v0 = vec[i];
float v1 = vec[i+1];
vec[i] = v0 * fcr - v1 * fci;
vec[i+1] = v0 * fci + v1 * fcr;
}
}
// multihead attention. iterate over all heads
int h;
#pragma omp parallel for private(h)
for (h = 0; h < p->n_heads; h++) {
// get the query vector for this head
float* q = s->q + h * head_size;
// attention scores for this head
float* att = s->att + h * p->seq_len;
// iterate over all timesteps, including the current one
for (int t = 0; t <= pos; t++) {
// get the key vector for this head and at this timestep
float* k = s->key_cache + loff + t * kv_dim + (h / kv_mul) * head_size;
// calculate the attention score as the dot product of q and k
float score = 0.0f;
for (int i = 0; i < head_size; i++) {
score += q[i] * k[i];
}
score /= sqrtf(head_size);
// save the score to the attention buffer
att[t] = score;
}
// softmax the scores to get attention weights, from 0..pos inclusively
softmax(att, pos + 1);
// weighted sum of the values, store back into xb
float* xb = s->xb + h * head_size;
memset(xb, 0, head_size * sizeof(float));
for (int t = 0; t <= pos; t++) {
// get the value vector for this head and at this timestep
float* v = s->value_cache + loff + t * kv_dim + (h / kv_mul) * head_size;
// get the attention weight for this timestep
float a = att[t];
// accumulate the weighted value into xb
for (int i = 0; i < head_size; i++) {
xb[i] += a * v[i];
}
}
}
// final matmul to get the output of the attention
matmul(s->xb2, s->xb, w->wo + l*dim*dim, dim, dim);
// residual connection back into x
for (int i = 0; i < dim; i++) {
x[i] += s->xb2[i];
}
// ffn rmsnorm
rmsnorm(s->xb, x, w->rms_ffn_weight + l*dim, dim);
// Now for FFN in PyTorch we have: self.w2(F.silu(self.w1(x)) * self.w3(x))
// first calculate self.w1(x) and self.w3(x)
matmul(s->hb, s->xb, w->w1 + l*dim*hidden_dim, dim, hidden_dim);
matmul(s->hb2, s->xb, w->w3 + l*dim*hidden_dim, dim, hidden_dim);
// SwiGLU non-linearity
for (int i = 0; i < hidden_dim; i++) {
float val = s->hb[i];
// silu(x)=x*σ(x), where σ(x) is the logistic sigmoid
val *= (1.0f / (1.0f + expf(-val)));
// elementwise multiply with w3(x)
val *= s->hb2[i];
s->hb[i] = val;
}
// final matmul to get the output of the ffn
matmul(s->xb, s->hb, w->w2 + l*dim*hidden_dim, hidden_dim, dim);
// residual connection
for (int i = 0; i < dim; i++) {
x[i] += s->xb[i];
}
}
// final rmsnorm
rmsnorm(x, x, w->rms_final_weight, dim);
// classifier into logits
matmul(s->logits, x, w->wcls, p->dim, p->vocab_size);
return s->logits;
}
// ----------------------------------------------------------------------------
// The Byte Pair Encoding (BPE) Tokenizer that translates strings <-> tokens
typedef struct {
char *str;
int id;
} TokenIndex;
typedef struct {
char** vocab;
float* vocab_scores;
TokenIndex *sorted_vocab;
int vocab_size;
unsigned int max_token_length;
unsigned char byte_pieces[512]; // stores all single-byte strings
} Tokenizer;
int compare_tokens(const void *a, const void *b) {
return strcmp(((TokenIndex*)a)->str, ((TokenIndex*)b)->str);
}
void build_tokenizer(Tokenizer* t, char* tokenizer_path, int vocab_size) {
// i should have written the vocab_size into the tokenizer file... sigh
t->vocab_size = vocab_size;
// malloc space to hold the scores and the strings
t->vocab = (char**)malloc(vocab_size * sizeof(char*));
t->vocab_scores = (float*)malloc(vocab_size * sizeof(float));
t->sorted_vocab = NULL; // initialized lazily
for (int i = 0; i < 256; i++) {
t->byte_pieces[i * 2] = (unsigned char)i;
t->byte_pieces[i * 2 + 1] = '\0';
}
// read in the file
FILE *file = fopen(tokenizer_path, "rb");
if (!file) { fprintf(stderr, "couldn't load %s\n", tokenizer_path); exit(EXIT_FAILURE); }
if (fread(&t->max_token_length, sizeof(int), 1, file) != 1) { fprintf(stderr, "failed read\n"); exit(EXIT_FAILURE); }
int len;
for (int i = 0; i < vocab_size; i++) {
if (fread(t->vocab_scores + i, sizeof(float), 1, file) != 1) { fprintf(stderr, "failed read\n"); exit(EXIT_FAILURE);}
if (fread(&len, sizeof(int), 1, file) != 1) { fprintf(stderr, "failed read\n"); exit(EXIT_FAILURE); }
t->vocab[i] = (char *)malloc(len + 1);
if (fread(t->vocab[i], len, 1, file) != 1) { fprintf(stderr, "failed read\n"); exit(EXIT_FAILURE); }
t->vocab[i][len] = '\0'; // add the string terminating token
}
fclose(file);
}
void free_tokenizer(Tokenizer* t) {
for (int i = 0; i < t->vocab_size; i++) { free(t->vocab[i]); }
free(t->vocab);
free(t->vocab_scores);
free(t->sorted_vocab);
}
char* decode(Tokenizer* t, int prev_token, int token) {
char *piece = t->vocab[token];
// following BOS (1) token, sentencepiece decoder strips any leading whitespace (see PR #89)
if (prev_token == 1 && piece[0] == ' ') { piece++; }
// careful, some tokens designate raw bytes, and look like e.g. '<0x01>'
// parse this and convert and return the actual byte
unsigned char byte_val;
if (sscanf(piece, "<0x%02hhX>", &byte_val) == 1) {
piece = (char*)t->byte_pieces + byte_val * 2;
}
return piece;
}
void safe_printf(char *piece) {
// piece might be a raw byte token, and we only want to print printable chars or whitespace
// because some of the other bytes can be various control codes, backspace, etc.
if (piece == NULL) { return; }
if (piece[0] == '\0') { return; }
if (piece[1] == '\0') {
unsigned char byte_val = piece[0];
if (!(isprint(byte_val) || isspace(byte_val))) {
return; // bad byte, don't print it
}
}
printf("%s", piece);
}
int str_lookup(char *str, TokenIndex *sorted_vocab, int vocab_size) {
// efficiently find the perfect match for str in vocab, return its index or -1 if not found
TokenIndex tok = { .str = str }; // acts as the key to search for
TokenIndex *res = bsearch(&tok, sorted_vocab, vocab_size, sizeof(TokenIndex), compare_tokens);
return res != NULL ? res->id : -1;
}
void encode(Tokenizer* t, char *text, int8_t bos, int8_t eos, int *tokens, int *n_tokens) {
// encode the string text (input) into an upper-bound preallocated tokens[] array
// bos != 0 means prepend the BOS token (=1), eos != 0 means append the EOS token (=2)
if (text == NULL) { fprintf(stderr, "cannot encode NULL text\n"); exit(EXIT_FAILURE); }
if (t->sorted_vocab == NULL) {
// lazily malloc and sort the vocabulary
t->sorted_vocab = malloc(t->vocab_size * sizeof(TokenIndex));
for (int i = 0; i < t->vocab_size; i++) {
t->sorted_vocab[i].str = t->vocab[i];
t->sorted_vocab[i].id = i;
}
qsort(t->sorted_vocab, t->vocab_size, sizeof(TokenIndex), compare_tokens);
}
// create a temporary buffer that will store merge candidates of always two consecutive tokens
// *2 for concat, +1 for null terminator +2 for UTF8 (in case max_token_length is 1)
char* str_buffer = malloc((t->max_token_length*2 +1 +2) * sizeof(char));
size_t str_len = 0;
// start at 0 tokens
*n_tokens = 0;
// add optional BOS (=1) token, if desired
if (bos) tokens[(*n_tokens)++] = 1;
// add_dummy_prefix is true by default
// so prepend a dummy prefix token to the input string, but only if text != ""
// TODO: pretty sure this isn't correct in the general case but I don't have the
// energy to read more of the sentencepiece code to figure out what it's doing
if (text[0] != '\0') {
int dummy_prefix = str_lookup(" ", t->sorted_vocab, t->vocab_size);
tokens[(*n_tokens)++] = dummy_prefix;
}
// Okay UTF-8 time. This will get messy. Here is the reference from Wikipedia:
// Code point ↔ UTF-8 conversion
// First code point Last code point Byte 1 Byte 2 Byte 3 Byte 4
// U+0000 U+007F 0xxxxxxx
// U+0080 U+07FF 110xxxxx 10xxxxxx
// U+0800 U+FFFF 1110xxxx 10xxxxxx 10xxxxxx
// U+10000 U+10FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
// process the raw (UTF-8) byte sequence of the input string
for (char *c = text; *c != '\0'; c++) {
// reset buffer if the current byte is ASCII or a leading byte
// 0xC0 is 11000000, so (*c & 0xC0) keeps the first 2 bits and zeros the rest
// 0x80 is 10000000
// in UTF-8, all continuation bytes start with "10" in first two bits
// so in English this is: "if this byte is not a continuation byte"
if ((*c & 0xC0) != 0x80) {
// this byte must be either a leading byte (11...) or an ASCII char (0x...)
// => reset our location, as we're starting a new UTF-8 codepoint
str_len = 0;
}
// append the current byte to the buffer
str_buffer[str_len++] = *c; // ++ is post-increment, incremented after this line
str_buffer[str_len] = '\0';
// while the next character is a continuation byte, continue appending
// but if there are too many of them, just stop to avoid overruning str_buffer size.
if ((*(c+1) & 0xC0) == 0x80 && str_len < 4) {
continue;
}
// ok c+1 is not a continuation byte, so we've read in a full codepoint
int id = str_lookup(str_buffer, t->sorted_vocab, t->vocab_size);
if (id != -1) {
// we found this codepoint in vocab, add it as a token
tokens[(*n_tokens)++] = id;
} else {
// byte_fallback encoding: just encode each byte as a token
// +3 is here because the first 3 vocab elements are <unk>, <s>, </s>
// so the individual bytes only start at index 3
for (int i=0; i < str_len; i++) {
tokens[(*n_tokens)++] = (unsigned char)str_buffer[i] + 3;
}
}
str_len = 0; // protect against a sequence of stray UTF8 continuation bytes
}
// merge the best consecutive pair each iteration, according the scores in vocab_scores
while (1) {
float best_score = -1e10;
int best_id = -1;
int best_idx = -1;
for (int i=0; i < (*n_tokens-1); i++) {
// check if we can merge the pair (tokens[i], tokens[i+1])
sprintf(str_buffer, "%s%s", t->vocab[tokens[i]], t->vocab[tokens[i+1]]);
int id = str_lookup(str_buffer, t->sorted_vocab, t->vocab_size);
if (id != -1 && t->vocab_scores[id] > best_score) {
// this merge pair exists in vocab! record its score and position
best_score = t->vocab_scores[id];
best_id = id;
best_idx = i;
}
}
if (best_idx == -1) {
break; // we couldn't find any more pairs to merge, so we're done
}
// merge the consecutive pair (best_idx, best_idx+1) into new token best_id
tokens[best_idx] = best_id;
// delete token at position best_idx+1, shift the entire sequence back 1
for (int i = best_idx+1; i < (*n_tokens-1); i++) {
tokens[i] = tokens[i+1];
}
(*n_tokens)--; // token length decreased
}
// add optional EOS (=2) token, if desired
if (eos) tokens[(*n_tokens)++] = 2;
free(str_buffer);
}
// ----------------------------------------------------------------------------
// The Sampler, which takes logits and returns a sampled token
// sampling can be done in a few ways: greedy argmax, sampling, top-p sampling
typedef struct {
float prob;
int index;
} ProbIndex; // struct used when sorting probabilities during top-p sampling
typedef struct {
int vocab_size;
ProbIndex* probindex; // buffer used in top-p sampling
float temperature;
float topp;
unsigned long long rng_state;
} Sampler;
int sample_argmax(float* probabilities, int n) {
// return the index that has the highest probability
int max_i = 0;
float max_p = probabilities[0];
for (int i = 1; i < n; i++) {
if (probabilities[i] > max_p) {
max_i = i;
max_p = probabilities[i];
}
}
return max_i;
}
int sample_mult(float* probabilities, int n, float coin) {
// sample index from probabilities (they must sum to 1!)
// coin is a random number in [0, 1), usually from random_f32()
float cdf = 0.0f;
for (int i = 0; i < n; i++) {
cdf += probabilities[i];
if (coin < cdf) {
return i;
}
}
return n - 1; // in case of rounding errors
}
int compare(const void* a, const void* b) {
ProbIndex* a_ = (ProbIndex*) a;
ProbIndex* b_ = (ProbIndex*) b;
if (a_->prob > b_->prob) return -1;
if (a_->prob < b_->prob) return 1;
return 0;
}
int sample_topp(float* probabilities, int n, float topp, ProbIndex* probindex, float coin) {
// top-p sampling (or "nucleus sampling") samples from the smallest set of
// tokens that exceed probability topp. This way we never sample tokens that
// have very low probabilities and are less likely to go "off the rails".
// coin is a random number in [0, 1), usually from random_f32()
int n0 = 0;
// quicksort indices in descending order of probabilities
// values smaller than (1 - topp) / (n - 1) cannot be part of the result
// so for efficiency we crop these out as candidates before sorting
const float cutoff = (1.0f - topp) / (n - 1);
for (int i = 0; i < n; i++) {
if (probabilities[i] >= cutoff) {
probindex[n0].index = i;
probindex[n0].prob = probabilities[i];
n0++;
}
}
qsort(probindex, n0, sizeof(ProbIndex), compare);
// truncate the list where cumulative probability exceeds topp
float cumulative_prob = 0.0f;
int last_idx = n0 - 1; // in case of rounding errors consider all elements
for (int i = 0; i < n0; i++) {
cumulative_prob += probindex[i].prob;
if (cumulative_prob > topp) {
last_idx = i;
break; // we've exceeded topp by including last_idx
}
}
// sample from the truncated list
float r = coin * cumulative_prob;
float cdf = 0.0f;
for (int i = 0; i <= last_idx; i++) {
cdf += probindex[i].prob;
if (r < cdf) {
return probindex[i].index;
}
}
return probindex[last_idx].index; // in case of rounding errors
}
void build_sampler(Sampler* sampler, int vocab_size, float temperature, float topp, unsigned long long rng_seed) {
sampler->vocab_size = vocab_size;
sampler->temperature = temperature;
sampler->topp = topp;
sampler->rng_state = rng_seed;
// buffer only used with nucleus sampling; may not need but it's ~small
sampler->probindex = malloc(sampler->vocab_size * sizeof(ProbIndex));
}
void free_sampler(Sampler* sampler) {
free(sampler->probindex);
}
unsigned int random_u32(unsigned long long *state) {
// xorshift rng: https://en.wikipedia.org/wiki/Xorshift#xorshift.2A
*state ^= *state >> 12;
*state ^= *state << 25;
*state ^= *state >> 27;
return (*state * 0x2545F4914F6CDD1Dull) >> 32;
}
float random_f32(unsigned long long *state) { // random float32 in [0,1)
return (random_u32(state) >> 8) / 16777216.0f;
}
int sample(Sampler* sampler, float* logits) {
// sample the token given the logits and some hyperparameters
int next;
if (sampler->temperature == 0.0f) {
// greedy argmax sampling: take the token with the highest probability
next = sample_argmax(logits, sampler->vocab_size);
} else {
// apply the temperature to the logits
for (int q=0; q<sampler->vocab_size; q++) { logits[q] /= sampler->temperature; }
// apply softmax to the logits to get the probabilities for next token
softmax(logits, sampler->vocab_size);
// flip a (float) coin (this is our source of entropy for sampling)
float coin = random_f32(&sampler->rng_state);
// we sample from this distribution to get the next token
if (sampler->topp <= 0 || sampler->topp >= 1) {
// simply sample from the predicted probability distribution
next = sample_mult(logits, sampler->vocab_size, coin);
} else {
// top-p (nucleus) sampling, clamping the least likely tokens to zero
next = sample_topp(logits, sampler->vocab_size, sampler->topp, sampler->probindex, coin);
}
}
return next;
}
// ----------------------------------------------------------------------------
// utilities: time
long time_in_ms() {
// return time in milliseconds, for benchmarking the model speed
struct timespec time;
clock_gettime(CLOCK_REALTIME, &time);
return time.tv_sec * 1000 + time.tv_nsec / 1000000;
}
// ----------------------------------------------------------------------------
// generation loop
void generate(Transformer *transformer, Tokenizer *tokenizer, Sampler *sampler, char *prompt, int steps) {
char *empty_prompt = "";
if (prompt == NULL) { prompt = empty_prompt; }
// encode the (string) prompt into tokens sequence
int num_prompt_tokens = 0;
int* prompt_tokens = (int*)malloc((strlen(prompt)+3) * sizeof(int)); // +3 for '\0', ?BOS, ?EOS
encode(tokenizer, prompt, 1, 0, prompt_tokens, &num_prompt_tokens);
if (num_prompt_tokens < 1) {
fprintf(stderr, "something is wrong, expected at least 1 prompt token\n");
exit(EXIT_FAILURE);
}
// start the main loop
long start = 0; // used to time our code, only initialized after first iteration
int next; // will store the next token in the sequence
int token = prompt_tokens[0]; // kick off with the first token in the prompt
int pos = 0; // position in the sequence
while (pos < steps) {
// forward the transformer to get logits for the next token
float* logits = forward(transformer, token, pos);
// advance the state machine
if (pos < num_prompt_tokens - 1) {
// if we are still processing the input prompt, force the next prompt token
next = prompt_tokens[pos + 1];
} else {
// otherwise sample the next token from the logits
next = sample(sampler, logits);
}
pos++;
// data-dependent terminating condition: the BOS (=1) token delimits sequences
if (next == 1) { break; }
// print the token as string, decode it with the Tokenizer object
char* piece = decode(tokenizer, token, next);
safe_printf(piece); // same as printf("%s", piece), but skips "unsafe" bytes
fflush(stdout);
token = next;
// init the timer here because the first iteration can be slower
if (start == 0) { start = time_in_ms(); }
}
printf("\n");
// report achieved tok/s (pos-1 because the timer starts after first iteration)
if (pos > 1) {
long end = time_in_ms();
fprintf(stderr, "achieved tok/s: %f\n", (pos-1) / (double)(end-start)*1000);
}
free(prompt_tokens);
}
void read_stdin(const char* guide, char* buffer, size_t bufsize) {
// read a line from stdin, up to but not including \n
printf("%s", guide);
if (fgets(buffer, bufsize, stdin) != NULL) {
size_t len = strlen(buffer);
if (len > 0 && buffer[len - 1] == '\n') {
buffer[len - 1] = '\0'; // strip newline
}
}
}
// ----------------------------------------------------------------------------
// chat loop
// I manually inspected the tokens for a few chat conversations compared to
// python reference and that seemed ok, but this was not thoroughly tested and
// is not safely implemented, it's more a proof of concept atm.
void chat(Transformer *transformer, Tokenizer *tokenizer, Sampler *sampler,
char *cli_user_prompt, char *cli_system_prompt, int steps) {
// buffers for reading the system prompt and user prompt from stdin
// you'll notice they are soomewhat haphazardly and unsafely set atm
char system_prompt[512];
char user_prompt[512];
char rendered_prompt[1152];
int num_prompt_tokens = 0;
int* prompt_tokens = (int*)malloc(1152 * sizeof(int));
int user_idx;
// start the main loop
int8_t user_turn = 1; // user starts
int next; // will store the next token in the sequence
int token; // stores the current token to feed into the transformer
int prev_token;
int pos = 0; // position in the sequence
while (pos < steps) {
// when it is the user's turn to contribute tokens to the dialog...
if (user_turn) {
// get the (optional) system prompt at position 0
if (pos == 0) {
// at position 0, the user can also contribute a system prompt
if (cli_system_prompt == NULL) {
// system prompt was not passed in, attempt to get it from stdin
read_stdin("Enter system prompt (optional): ", system_prompt, sizeof(system_prompt));
} else {
// system prompt was passed in, use it
strcpy(system_prompt, cli_system_prompt);
}
}
// get the user prompt
if (pos == 0 && cli_user_prompt != NULL) {
// user prompt for position 0 was passed in, use it
strcpy(user_prompt, cli_user_prompt);
} else {
// otherwise get user prompt from stdin
read_stdin("User: ", user_prompt, sizeof(user_prompt));
}
// render user/system prompts into the Llama 2 Chat schema
if (pos == 0 && system_prompt[0] != '\0') {
char system_template[] = "[INST] <<SYS>>\n%s\n<</SYS>>\n\n%s [/INST]";
sprintf(rendered_prompt, system_template, system_prompt, user_prompt);
} else {
char user_template[] = "[INST] %s [/INST]";
sprintf(rendered_prompt, user_template, user_prompt);
}
// encode the rendered prompt into tokens
encode(tokenizer, rendered_prompt, 1, 0, prompt_tokens, &num_prompt_tokens);
user_idx = 0; // reset the user index
user_turn = 0;
printf("Assistant: ");
}
// determine the token to pass into the transformer next
if (user_idx < num_prompt_tokens) {
// if we are still processing the input prompt, force the next prompt token
token = prompt_tokens[user_idx++];
} else {
// otherwise use the next token sampled from previous turn
token = next;
}
// EOS (=2) token ends the Assistant turn
if (token == 2) { user_turn = 1; }
// forward the transformer to get logits for the next token
float* logits = forward(transformer, token, pos);
next = sample(sampler, logits);
pos++;
if (user_idx >= num_prompt_tokens && next != 2) {
// the Assistant is responding, so print its output
char* piece = decode(tokenizer, token, next);
safe_printf(piece); // same as printf("%s", piece), but skips "unsafe" bytes
fflush(stdout);
}
if (next == 2) { printf("\n"); }
}
printf("\n");
free(prompt_tokens);
}
// ----------------------------------------------------------------------------
// CLI, include only if not testing
#ifndef TESTING
void error_usage() {
fprintf(stderr, "Usage: run <checkpoint> [options]\n");
fprintf(stderr, "Example: run model.bin -n 256 -i \"Once upon a time\"\n");
fprintf(stderr, "Options:\n");
fprintf(stderr, " -t <float> temperature in [0,inf], default 1.0\n");
fprintf(stderr, " -p <float> p value in top-p (nucleus) sampling in [0,1] default 0.9\n");
fprintf(stderr, " -s <int> random seed, default time(NULL)\n");
fprintf(stderr, " -n <int> number of steps to run for, default 256. 0 = max_seq_len\n");
fprintf(stderr, " -i <string> input prompt\n");
fprintf(stderr, " -z <string> optional path to custom tokenizer\n");
fprintf(stderr, " -m <string> mode: generate|chat, default: generate\n");
fprintf(stderr, " -y <string> (optional) system prompt in chat mode\n");
exit(EXIT_FAILURE);
}
int main(int argc, char *argv[]) {
// default parameters
char *checkpoint_path = NULL; // e.g. out/model.bin
char *tokenizer_path = "tokenizer.bin";
float temperature = 1.0f; // 0.0 = greedy deterministic. 1.0 = original. don't set higher
float topp = 0.9f; // top-p in nucleus sampling. 1.0 = off. 0.9 works well, but slower
int steps = 256; // number of steps to run for
char *prompt = NULL; // prompt string
unsigned long long rng_seed = 0; // seed rng with time by default
char *mode = "generate"; // generate|chat
char *system_prompt = NULL; // the (optional) system prompt to use in chat mode
// poor man's C argparse so we can override the defaults above from the command line
if (argc >= 2) { checkpoint_path = argv[1]; } else { error_usage(); }
for (int i = 2; i < argc; i+=2) {
// do some basic validation
if (i + 1 >= argc) { error_usage(); } // must have arg after flag
if (argv[i][0] != '-') { error_usage(); } // must start with dash
if (strlen(argv[i]) != 2) { error_usage(); } // must be -x (one dash, one letter)
// read in the args
if (argv[i][1] == 't') { temperature = atof(argv[i + 1]); }
else if (argv[i][1] == 'p') { topp = atof(argv[i + 1]); }
else if (argv[i][1] == 's') { rng_seed = atoi(argv[i + 1]); }
else if (argv[i][1] == 'n') { steps = atoi(argv[i + 1]); }
else if (argv[i][1] == 'i') { prompt = argv[i + 1]; }
else if (argv[i][1] == 'z') { tokenizer_path = argv[i + 1]; }
else if (argv[i][1] == 'm') { mode = argv[i + 1]; }
else if (argv[i][1] == 'y') { system_prompt = argv[i + 1]; }
else { error_usage(); }
}
// parameter validation/overrides
if (rng_seed <= 0) rng_seed = (unsigned int)time(NULL);
if (temperature < 0.0) temperature = 0.0;
if (topp < 0.0 || 1.0 < topp) topp = 0.9;
if (steps < 0) steps = 0;
// build the Transformer via the model .bin file
Transformer transformer;
build_transformer(&transformer, checkpoint_path);
if (steps == 0 || steps > transformer.config.seq_len) steps = transformer.config.seq_len; // override to ~max length
// build the Tokenizer via the tokenizer .bin file
Tokenizer tokenizer;
build_tokenizer(&tokenizer, tokenizer_path, transformer.config.vocab_size);
// build the Sampler
Sampler sampler;
build_sampler(&sampler, transformer.config.vocab_size, temperature, topp, rng_seed);
// run!
if (strcmp(mode, "generate") == 0) {
generate(&transformer, &tokenizer, &sampler, prompt, steps);
} else if (strcmp(mode, "chat") == 0) {
chat(&transformer, &tokenizer, &sampler, prompt, system_prompt, steps);
} else {
fprintf(stderr, "unknown mode: %s\n", mode);
error_usage();
}
// memory and file handles cleanup
free_sampler(&sampler);
free_tokenizer(&tokenizer);
free_transformer(&transformer);
return 0;
}
#endif

View File

@@ -1,6 +0,0 @@
{
"cl": [
"clang -emit-llvm -S -o llgo_autogen.ll -c llama2/run.c",
"rm llgo_autogen.lla; zip llgo_autogen.lla llgo_autogen.ll"
]
}

Binary file not shown.

151
c/math/cmplx/complex.go Normal file
View File

@@ -0,0 +1,151 @@
/*
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cmplx
import (
_ "unsafe"
)
const (
LLGoPackage = "decl"
)
// -----------------------------------------------------------------------------
//go:linkname Abs C.cabs
func Abs(z complex128) float64
//go:linkname Acos C.cacos
func Acos(z complex128) complex128
//go:linkname Acosh C.cacosh
func Acosh(z complex128) complex128
//go:linkname Asin C.casin
func Asin(z complex128) complex128
//go:linkname Asinh C.casinh
func Asinh(z complex128) complex128
//go:linkname Atan C.catan
func Atan(z complex128) complex128
//go:linkname Atanh C.catanh
func Atanh(z complex128) complex128
//go:linkname Cos C.ccos
func Cos(z complex128) complex128
//go:linkname Cosh C.ccosh
func Cosh(z complex128) complex128
//go:linkname Exp C.cexp
func Exp(z complex128) complex128
//go:linkname Log C.clog
func Log(z complex128) complex128
//go:linkname Log10 C.clog10
func Log10(z complex128) complex128
//go:linkname Arg C.carg
func Arg(z complex128) float64
//go:linkname Phase C.carg
func Phase(z complex128) float64
//go:linkname Pow C.cpow
func Pow(x, y complex128) complex128
//go:linkname Sin C.csin
func Sin(z complex128) complex128
//go:linkname Sinh C.csinh
func Sinh(z complex128) complex128
//go:linkname Sqrt C.csqrt
func Sqrt(z complex128) complex128
//go:linkname Tan C.ctan
func Tan(z complex128) complex128
//go:linkname Tanh C.ctanh
func Tanh(z complex128) complex128
// -----------------------------------------------------------------------------
//go:linkname Absf C.cabsf
func Absf(z complex64) float32
//go:linkname Acosf C.cacosf
func Acosf(z complex64) complex64
//go:linkname Acoshf C.cacoshf
func Acoshf(z complex64) complex64
//go:linkname Asinf C.casinf
func Asinf(z complex64) complex64
//go:linkname Asinhf C.casinhf
func Asinhf(z complex64) complex64
//go:linkname Atanf C.catanf
func Atanf(z complex64) complex64
//go:linkname Atanhf C.catanhf
func Atanhf(z complex64) complex64
//go:linkname Cosf C.ccosf
func Cosf(z complex64) complex64
//go:linkname Coshf C.ccoshf
func Coshf(z complex64) complex64
//go:linkname Expf C.cexpf
func Expf(z complex64) complex64
//go:linkname Logf C.clogf
func Logf(z complex64) complex64
//go:linkname Log10f C.clog10f
func Log10f(z complex64) complex64
//go:linkname Argf C.cargf
func Argf(z complex64) float32
//go:linkname Phasef C.cargf
func Phasef(z complex64) float32
//go:linkname Powf C.cpowf
func Powf(x, y complex64) complex64
//go:linkname Sinf C.csinf
func Sinf(z complex64) complex64
//go:linkname Sinhf C.csinhf
func Sinhf(z complex64) complex64
//go:linkname Sqrtf C.csqrtf
func Sqrtf(z complex64) complex64
//go:linkname Tanf C.ctanf
func Tanf(z complex64) complex64
//go:linkname Tanhf C.ctanhf
func Tanhf(z complex64) complex64
// -----------------------------------------------------------------------------

333
c/math/math.go Normal file
View File

@@ -0,0 +1,333 @@
/*
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package math
import (
_ "unsafe"
"github.com/goplus/llgo/c"
)
const (
LLGoPackage = "decl"
)
// -----------------------------------------------------------------------------
//go:linkname Acos C.acos
func Acos(x float64) float64
//go:linkname Acosh C.acosh
func Acosh(x float64) float64
//go:linkname Asin C.asin
func Asin(x float64) float64
//go:linkname Asinh C.asinh
func Asinh(x float64) float64
//go:linkname Atan C.atan
func Atan(x float64) float64
//go:linkname Atan2 C.atan2
func Atan2(y, x float64) float64
//go:linkname Atanh C.atanh
func Atanh(x float64) float64
//go:linkname Cbrt C.cbrt
func Cbrt(x float64) float64
//go:linkname Ceil C.ceil
func Ceil(x float64) float64
//go:linkname Cos C.cos
func Cos(x float64) float64
//go:linkname Cosh C.cosh
func Cosh(x float64) float64
//go:linkname Copysign C.copysign
func Copysign(x, y float64) float64
//go:linkname Erf C.erf
func Erf(x float64) float64
//go:linkname Erfc C.erfc
func Erfc(x float64) float64
//go:linkname Exp C.exp
func Exp(x float64) float64
//go:linkname Exp2 C.exp2
func Exp2(x float64) float64
//go:linkname Expm1 C.expm1
func Expm1(x float64) float64
//go:linkname Fdim C.fdim
func Fdim(x, y float64) float64
//go:linkname Floor C.floor
func Floor(x float64) float64
//go:linkname Fma C.fma
func Fma(x, y, z float64) float64
//go:linkname Fmax C.fmax
func Fmax(x, y float64) float64
//go:linkname Fmin C.fmin
func Fmin(x, y float64) float64
//go:linkname Fmod C.fmod
func Fmod(x, y float64) float64
//go:linkname Frexp C.frexp
func Frexp(x float64, exp *c.Int) float64
//go:linkname Gamma C.gamma
func Gamma(x float64) float64
//go:linkname Hypot C.hypot
func Hypot(x, y float64) float64
//go:linkname Ilogb C.ilogb
func Ilogb(x float64) c.Int
//go:linkname J0 C.j0
func J0(x float64) float64
//go:linkname J1 C.j1
func J1(x float64) float64
//go:linkname Jn C.jn
func Jn(n c.Int, x float64) float64
//go:linkname Ldexp C.ldexp
func Ldexp(x float64, exp c.Int) float64
//go:linkname Lgamma C.lgamma
func Lgamma(x float64) float64
//go:linkname Log C.log
func Log(x float64) float64
//go:linkname Log10 C.log10
func Log10(x float64) float64
//go:linkname Log1p C.log1p
func Log1p(x float64) float64
//go:linkname Log2 C.log2
func Log2(x float64) float64
//go:linkname Logb C.logb
func Logb(x float64) float64
//go:linkname Modf C.modf
func Modf(x float64, ipart *float64) float64
//go:linkname Nan C.nan
func Nan(tag *c.Char) float64
//go:linkname Nextafter C.nextafter
func Nextafter(x, y float64) float64
//go:linkname Pow C.pow
func Pow(x, y float64) float64
//go:linkname Remainder C.remainder
func Remainder(x, y float64) float64
//go:linkname Round C.round
func Round(x float64) float64
//go:linkname Sin C.sin
func Sin(x float64) float64
//go:linkname Sinh C.sinh
func Sinh(x float64) float64
//go:linkname Sqrt C.sqrt
func Sqrt(x float64) float64
//go:linkname Tan C.tan
func Tan(x float64) float64
//go:linkname Tanh C.tanh
func Tanh(x float64) float64
//go:linkname Tgamma C.tgamma
func Tgamma(x float64) float64
//go:linkname Trunc C.trunc
func Trunc(x float64) float64
// -----------------------------------------------------------------------------
//go:linkname Acosf C.acosf
func Acosf(x float32) float32
//go:linkname Acoshf C.acoshf
func Acoshf(x float32) float32
//go:linkname Asinf C.asinf
func Asinf(x float32) float32
//go:linkname Asinhf C.asinhf
func Asinhf(x float32) float32
//go:linkname Atanf C.atanf
func Atanf(x float32) float32
//go:linkname Atan2f C.atan2f
func Atan2f(y, x float32) float32
//go:linkname Atanhf C.atanhf
func Atanhf(x float32) float32
//go:linkname Cbrtf C.cbrtf
func Cbrtf(x float32) float32
//go:linkname Ceilf C.ceilf
func Ceilf(x float32) float32
//go:linkname Cosf C.cosf
func Cosf(x float32) float32
//go:linkname Coshf C.coshf
func Coshf(x float32) float32
//go:linkname Copysignf C.copysignf
func Copysignf(x, y float32) float32
//go:linkname Erff C.erff
func Erff(x float32) float32
//go:linkname Erfcf C.erfcf
func Erfcf(x float32) float32
//go:linkname Expf C.expf
func Expf(x float32) float32
//go:linkname Exp2f C.exp2f
func Exp2f(x float32) float32
//go:linkname Expm1f C.expm1f
func Expm1f(x float32) float32
//go:linkname Fdimf C.fdimf
func Fdimf(x, y float32) float32
//go:linkname Floorf C.floorf
func Floorf(x float32) float32
//go:linkname Fmaf C.fmaf
func Fmaf(x, y, z float32) float32
//go:linkname Fmaxf C.fmaxf
func Fmaxf(x, y float32) float32
//go:linkname Fminf C.fminf
func Fminf(x, y float32) float32
//go:linkname Fmodf C.fmodf
func Fmodf(x, y float32) float32
//go:linkname Frexpf C.frexpf
func Frexpf(x float32, exp *c.Int) float32
//go:linkname Gammaf C.gammaf
func Gammaf(x float32) float32
//go:linkname Hypotf C.hypotf
func Hypotf(x, y float32) float32
//go:linkname Ilogbf C.ilogbf
func Ilogbf(x float32) c.Int
//go:linkname J0f C.j0f
func J0f(x float32) float32
//go:linkname J1f C.j1f
func J1f(x float32) float32
//go:linkname Jnf C.jnf
func Jnf(n c.Int, x float32) float32
//go:linkname Ldexpf C.ldexpf
func Ldexpf(x float32, exp c.Int) float32
//go:linkname Lgammaf C.lgammaf
func Lgammaf(x float32) float32
//go:linkname Logf C.logf
func Logf(x float32) float32
//go:linkname Log10f C.log10f
func Log10f(x float32) float32
//go:linkname Log1pf C.log1pf
func Log1pf(x float32) float32
//go:linkname Log2f C.log2f
func Log2f(x float32) float32
//go:linkname Logbf C.logbf
func Logbf(x float32) float32
//go:linkname Modff C.modff
func Modff(x float32, ipart *float32) float32
//go:linkname Nanf C.nanf
func Nanf(tag *c.Char) float32
//go:linkname Nextafterf C.nextafterf
func Nextafterf(x, y float32) float32
//go:linkname Powf C.powf
func Powf(x, y float32) float32
//go:linkname Remainderf C.remainderf
func Remainderf(x, y float32) float32
//go:linkname Roundf C.roundf
func Roundf(x float32) float32
//go:linkname Sinf C.sinf
func Sinf(x float32) float32
//go:linkname Sinhf C.sinhf
func Sinhf(x float32) float32
//go:linkname Sqrtf C.sqrtf
func Sqrtf(x float32) float32
//go:linkname Tanf C.tanf
func Tanf(x float32) float32
//go:linkname Tanhf C.tanhf
func Tanhf(x float32) float32
//go:linkname Tgammaf C.tgammaf
func Tgammaf(x float32) float32
//go:linkname Truncf C.truncf
func Truncf(x float32) float32
// -----------------------------------------------------------------------------

54
c/math/rand/rand.go Normal file
View File

@@ -0,0 +1,54 @@
/*
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package rand
import (
_ "unsafe"
"github.com/goplus/llgo/c"
)
const (
LLGoPackage = "decl"
)
// -----------------------------------------------------------------------------
//go:linkname Rand C.rand
func Rand() c.Int
//go:linkname RandR C.rand_r
func RandR(*c.Uint) c.Int
//go:linkname Srand C.srand
func Srand(c.Uint)
//go:linkname Sranddev C.sranddev
func Sranddev()
// -----------------------------------------------------------------------------
//go:linkname Random C.random
func Random() c.Long
//go:linkname Srandom C.srandom
func Srandom(c.Uint)
//go:linkname Srandomdev C.srandomdev
func Srandomdev()
// -----------------------------------------------------------------------------

231
c/os/os.go Normal file
View File

@@ -0,0 +1,231 @@
/*
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package os
// #include <sys/stat.h>
// #include <limits.h>
import "C"
import (
_ "unsafe"
"github.com/goplus/llgo/c"
)
const (
LLGoPackage = "decl"
)
const (
PATH_MAX = C.PATH_MAX
)
type (
ModeT C.mode_t
UidT C.uid_t
GidT C.gid_t
OffT C.off_t
DevT C.dev_t
StatT C.struct_stat
)
//go:linkname Errno errno
var Errno c.Int
//go:linkname Umask C.umask
func Umask(cmask ModeT) ModeT
//go:linkname Mkdir C.mkdir
func Mkdir(path *c.Char, mode ModeT) c.Int
//go:linkname Rmdir C.rmdir
func Rmdir(path *c.Char) c.Int
//go:linkname Link C.link
func Link(oldpath *c.Char, newpath *c.Char) c.Int
//go:linkname Symlink C.symlink
func Symlink(target *c.Char, linkpath *c.Char) c.Int
//go:linkname Readlink C.readlink
func Readlink(path *c.Char, buf c.Pointer, bufsize uintptr) int
//go:linkname Unlink C.unlink
func Unlink(path *c.Char) c.Int
//go:linkname Remove C.remove
func Remove(path *c.Char) c.Int
//go:linkname Rename C.rename
func Rename(oldpath *c.Char, newpath *c.Char) c.Int
//go:linkname Stat C.stat
func Stat(path *c.Char, buf *StatT) c.Int
//go:linkname Lstat C.lstat
func Lstat(path *c.Char, buf *StatT) c.Int
//go:linkname Truncate C.truncate
func Truncate(path *c.Char, length OffT) c.Int
//go:linkname Chmod C.chmod
func Chmod(path *c.Char, mode ModeT) c.Int
//go:linkname Chown C.chown
func Chown(path *c.Char, owner UidT, group GidT) c.Int
//go:linkname Lchown C.lchown
func Lchown(path *c.Char, owner UidT, group GidT) c.Int
// -----------------------------------------------------------------------------
//go:linkname Getcwd C.getcwd
func Getcwd(buffer c.Pointer, size uintptr) *c.Char
//go:linkname Chdir C.chdir
func Chdir(path *c.Char) c.Int
//go:linkname Chroot C.chroot
func Chroot(path *c.Char) c.Int
// -----------------------------------------------------------------------------
//go:linkname Environ C.environ
func Environ() **c.Char
//go:linkname Getenv C.getenv
func Getenv(name *c.Char) *c.Char
//go:linkname Setenv C.setenv
func Setenv(name *c.Char, value *c.Char, overwrite c.Int) c.Int
//go:linkname Putenv C.putenv
func Putenv(env *c.Char) c.Int
//go:linkname Unsetenv C.unsetenv
func Unsetenv(name *c.Char) c.Int
//go:linkname Clearenv C.clearenv
func Clearenv()
// -----------------------------------------------------------------------------
//go:linkname Fchdir C.fchdir
func Fchdir(dirfd c.Int) c.Int
//go:linkname Faccessat C.faccessat
func Faccessat(dirfd c.Int, path *c.Char, mode c.Int, flags c.Int) c.Int
//go:linkname Fchmodat C.fchmodat
func Fchmodat(dirfd c.Int, path *c.Char, mode ModeT, flags c.Int) c.Int
//go:linkname Fchownat C.fchownat
func Fchownat(dirfd c.Int, path *c.Char, owner UidT, group GidT, flags c.Int) c.Int
//go:linkname Fstatat C.fstatat
func Fstatat(dirfd c.Int, path *c.Char, buf *StatT, flags c.Int) c.Int
// -----------------------------------------------------------------------------
//go:linkname Open C.open
func Open(path *c.Char, flags c.Int, mode ModeT) c.Int
//go:linkname Openat C.openat
func Openat(dirfd c.Int, path *c.Char, flags c.Int, mode ModeT) c.Int
//go:linkname Creat C.creat
func Creat(path *c.Char, mode ModeT) c.Int
//go:linkname Dup C.dup
func Dup(fd c.Int) c.Int
//go:linkname Dup2 C.dup2
func Dup2(oldfd c.Int, newfd c.Int) c.Int
/* TODO(xsw):
On Alpha, IA-64, MIPS, SuperH, and SPARC/SPARC64, pipe() has the following prototype:
struct fd_pair {
long fd[2];
};
struct fd_pair pipe(void);
*/
//go:linkname Pipe C.pipe
func Pipe(fds *[2]c.Int) c.Int
//go:linkname Mkfifo C.mkfifo
func Mkfifo(path *c.Char, mode ModeT) c.Int
//go:linkname Mknod C.mknod
func Mknod(path *c.Char, mode ModeT, dev DevT) c.Int
//go:linkname Close C.close
func Close(fd c.Int) c.Int
//go:linkname Read C.read
func Read(fd c.Int, buf c.Pointer, count uintptr) int
//go:linkname Write C.write
func Write(fd c.Int, buf c.Pointer, count uintptr) int
//go:linkname Lseek C.lseek
func Lseek(fd c.Int, offset OffT, whence c.Int) OffT
//go:linkname Fsync C.fsync
func Fsync(fd c.Int) c.Int
//go:linkname Ftruncate C.ftruncate
func Ftruncate(fd c.Int, length OffT) c.Int
//go:linkname Fchmod C.fchmod
func Fchmod(fd c.Int, mode ModeT) c.Int
//go:linkname Fchown C.fchown
func Fchown(fd c.Int, owner UidT, group GidT) c.Int
//go:linkname Fstat C.fstat
func Fstat(fd c.Int, buf *StatT) c.Int
//go:linkname Isatty C.isatty
func Isatty(fd c.Int) c.Int
// -----------------------------------------------------------------------------
//go:linkname Kill C.kill
func Kill(pid c.Int, sig c.Int) c.Int
//go:linkname Exit C.exit
func Exit(c.Int)
//go:linkname Getpid C.getpid
func Getpid() c.Int
//go:linkname Getppid C.getppid
func Getppid() c.Int
//go:linkname Getuid C.getuid
func Getuid() UidT
//go:linkname Geteuid C.geteuid
func Geteuid() UidT
//go:linkname Getgid C.getgid
func Getgid() GidT
//go:linkname Getegid C.getegid
func Getegid() GidT
// -----------------------------------------------------------------------------

160
c/pthread/pthread.go Normal file
View File

@@ -0,0 +1,160 @@
/*
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package pthread
import (
_ "unsafe"
"github.com/goplus/llgo/c"
)
const (
LLGoPackage = "decl"
)
func __noop__() c.Int {
return 0
}
// -----------------------------------------------------------------------------
type aThread struct {
Unused [8]byte
}
// Thread represents a POSIX thread.
type Thread = *aThread
// The pthread_create() function starts a new thread in the calling
// process. The new thread starts execution by invoking
// start_routine(); arg is passed as the sole argument of
// start_routine().
//
// The new thread terminates in one of the following ways:
//
// - It calls pthread_exit(3), specifying an exit status value that
// is available to another thread in the same process that calls
// pthread_join(3).
//
// - It returns from start_routine(). This is equivalent to
// calling pthread_exit(3) with the value supplied in the return
// statement.
//
// - It is canceled (see pthread_cancel(3)).
//
// - Any of the threads in the process calls exit(3), or the main
// thread performs a return from main(). This causes the
// termination of all threads in the process.
//
// On success, pthread_create() returns 0; on error, it returns an
// error number, and the contents of *thread are undefined.
//
// See https://man7.org/linux/man-pages/man3/pthread_create.3.html
//
//go:linkname Create C.pthread_create
func Create(pthread *Thread, attr *Attr, routine func(c.Pointer) c.Pointer, arg c.Pointer) c.Int
// The pthread_join() function waits for the thread specified by
// thread to terminate. If that thread has already terminated, then
// pthread_join() returns immediately. The thread specified by
// thread must be joinable.
//
// If retval is not NULL, then pthread_join() copies the exit status
// of the target thread (i.e., the value that the target thread
// supplied to pthread_exit(3)) into the location pointed to by
// retval. If the target thread was canceled, then PTHREAD_CANCELED
// is placed in the location pointed to by retval.
//
// If multiple threads simultaneously try to join with the same
// thread, the results are undefined. If the thread calling
// pthread_join() is canceled, then the target thread will remain
// joinable (i.e., it will not be detached).
//
// See https://man7.org/linux/man-pages/man3/pthread_join.3.html
//
//go:linkname Join C.pthread_join
func Join(thread Thread, retval *c.Pointer) c.Int
// The pthread_exit() function terminates the calling thread and
// returns a value via retval that (if the thread is joinable) is
// available to another thread in the same process that calls
// pthread_join(3).
//
// See https://man7.org/linux/man-pages/man3/pthread_exit.3.html
//
//go:linkname Exit C.pthread_exit
func Exit(retval c.Pointer)
// The pthread_cancel() function sends a cancelation request to the
// thread thread.
//
// See https://man7.org/linux/man-pages/man3/pthread_cancel.3.html
//
//go:linkname Cancel C.pthread_cancel
func Cancel(thread Thread) c.Int
// -----------------------------------------------------------------------------
// Attr represents a POSIX thread attributes.
type Attr struct {
Detached byte
SsSp *c.Char
SsSize uintptr
}
// llgo:link (*Attr).Init C.pthread_attr_init
func (attr *Attr) Init() c.Int { return 0 }
// llgo:link (*Attr).Destroy C.pthread_attr_destroy
func (attr *Attr) Destroy() c.Int { return 0 }
// llgo:link (*Attr).GetDetached C.pthread_attr_getdetachstate
func (attr *Attr) GetDetached(detached *c.Int) c.Int { return 0 }
// llgo:link (*Attr).SetDetached C.pthread_attr_setdetachstate
func (attr *Attr) SetDetached(detached c.Int) c.Int { return 0 }
// llgo:link (*Attr).GetStackSize C.pthread_attr_getstacksize
func (attr *Attr) GetStackSize(stackSize *uintptr) c.Int { return 0 }
// llgo:link (*Attr).SetStackSize C.pthread_attr_setstacksize
func (attr *Attr) SetStackSize(stackSize uintptr) c.Int { return 0 }
// llgo:link (*Attr).GetStackAddr C.pthread_attr_getstackaddr
func (attr *Attr) GetStackAddr(stackAddr *c.Pointer) c.Int { return 0 }
// llgo:link (*Attr).SetStackAddr C.pthread_attr_setstackaddr
func (attr *Attr) SetStackAddr(stackAddr c.Pointer) c.Int { return 0 }
// -----------------------------------------------------------------------------
// Thread Local Storage
type Key c.Uint
// llgo:link (*Key).Create C.pthread_key_create
func (key *Key) Create(destructor func(c.Pointer)) c.Int { return 0 }
// llgo:link Key.Delete C.pthread_key_delete
func (key Key) Delete() c.Int { return 0 }
// llgo:link Key.Get C.pthread_getspecific
func (key Key) Get() c.Pointer { return nil }
// llgo:link Key.Set C.pthread_setspecific
func (key Key) Set(value c.Pointer) c.Int { return __noop__() }
// -----------------------------------------------------------------------------

View File

@@ -0,0 +1,7 @@
#include <pthread.h>
// -----------------------------------------------------------------------------
pthread_once_t llgoSyncOnceInitVal = PTHREAD_ONCE_INIT;
// -----------------------------------------------------------------------------

Binary file not shown.

174
c/pthread/sync/sync.go Normal file
View File

@@ -0,0 +1,174 @@
/*
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sync
// #include <pthread.h>
import "C"
import (
_ "unsafe"
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/time"
)
const (
LLGoFiles = "_pthd/pthd.c"
LLGoPackage = "link"
)
// -----------------------------------------------------------------------------
// Once is an object that will perform exactly one action.
type Once C.pthread_once_t
//go:linkname OnceInit llgoSyncOnceInitVal
var OnceInit Once
// llgo:link (*Once).Do C.pthread_once
func (o *Once) Do(f func()) c.Int { return 0 }
// -----------------------------------------------------------------------------
type MutexType c.Int
const (
MUTEX_NORMAL MutexType = C.PTHREAD_MUTEX_NORMAL
MUTEX_ERRORCHECK MutexType = C.PTHREAD_MUTEX_ERRORCHECK
MUTEX_RECURSIVE MutexType = C.PTHREAD_MUTEX_RECURSIVE
MUTEX_DEFAULT MutexType = C.PTHREAD_MUTEX_DEFAULT
)
// MutexAttr is a mutex attribute object.
type MutexAttr C.pthread_mutexattr_t
// llgo:link (*MutexAttr).Init C.pthread_mutexattr_init
func (a *MutexAttr) Init(attr *MutexAttr) c.Int { return 0 }
// llgo:link (*MutexAttr).Destroy C.pthread_mutexattr_destroy
func (a *MutexAttr) Destroy() {}
// llgo:link (*MutexAttr).SetType C.pthread_mutexattr_settype
func (a *MutexAttr) SetType(typ MutexType) c.Int { return 0 }
// -----------------------------------------------------------------------------
// Mutex is a mutual exclusion lock.
type Mutex C.pthread_mutex_t
// llgo:link (*Mutex).Init C.pthread_mutex_init
func (m *Mutex) Init(attr *MutexAttr) c.Int { return 0 }
// llgo:link (*Mutex).Destroy C.pthread_mutex_destroy
func (m *Mutex) Destroy() {}
// llgo:link (*Mutex).Lock C.pthread_mutex_lock
func (m *Mutex) Lock() {}
// llgo:link (*Mutex).TryLock C.pthread_mutex_trylock
func (m *Mutex) TryLock() c.Int { return 0 }
// llgo:link (*Mutex).Unlock C.pthread_mutex_unlock
func (m *Mutex) Unlock() {}
// -----------------------------------------------------------------------------
// RWLockAttr is a read-write lock attribute object.
type RWLockAttr C.pthread_rwlockattr_t
// llgo:link (*RWLockAttr).Init C.pthread_rwlockattr_init
func (a *RWLockAttr) Init(attr *RWLockAttr) c.Int { return 0 }
// llgo:link (*RWLockAttr).Destroy C.pthread_rwlockattr_destroy
func (a *RWLockAttr) Destroy() {}
// llgo:link (*RWLockAttr).SetPShared C.pthread_rwlockattr_setpshared
func (a *RWLockAttr) SetPShared(pshared c.Int) c.Int { return 0 }
// llgo:link (*RWLockAttr).GetPShared C.pthread_rwlockattr_getpshared
func (a *RWLockAttr) GetPShared(pshared *c.Int) c.Int { return 0 }
// -----------------------------------------------------------------------------
// RWLock is a read-write lock.
type RWLock C.pthread_rwlock_t
// llgo:link (*RWLock).Init C.pthread_rwlock_init
func (rw *RWLock) Init(attr *RWLockAttr) c.Int { return 0 }
// llgo:link (*RWLock).Destroy C.pthread_rwlock_destroy
func (rw *RWLock) Destroy() {}
// llgo:link (*RWLock).RLock C.pthread_rwlock_rdlock
func (rw *RWLock) RLock() {}
// llgo:link (*RWLock).TryRLock C.pthread_rwlock_tryrdlock
func (rw *RWLock) TryRLock() c.Int { return 0 }
// llgo:link (*RWLock).RUnlock C.pthread_rwlock_unlock
func (rw *RWLock) RUnlock() {}
// llgo:link (*RWLock).Lock C.pthread_rwlock_wrlock
func (rw *RWLock) Lock() {}
// llgo:link (*RWLock).TryLock C.pthread_rwlock_trywrlock
func (rw *RWLock) TryLock() c.Int { return 0 }
// llgo:link (*RWLock).Unlock C.pthread_rwlock_unlock
func (rw *RWLock) Unlock() {}
// -----------------------------------------------------------------------------
// CondAttr is a condition variable attribute object.
type CondAttr C.pthread_condattr_t
// llgo:link (*CondAttr).Init C.pthread_condattr_init
func (a *CondAttr) Init(attr *CondAttr) c.Int { return 0 }
// llgo:link (*CondAttr).Destroy C.pthread_condattr_destroy
func (a *CondAttr) Destroy() {}
// llgo:link (*CondAttr).SetClock C.pthread_condattr_setclock
func (a *CondAttr) SetClock(clock time.ClockidT) c.Int { return 0 }
// llgo:link (*CondAttr).GetClock C.pthread_condattr_getclock
func (a *CondAttr) GetClock(clock *time.ClockidT) c.Int { return 0 }
// -----------------------------------------------------------------------------
// Cond is a condition variable.
type Cond C.pthread_cond_t
// llgo:link (*Cond).Init C.pthread_cond_init
func (c *Cond) Init(attr *CondAttr) c.Int { return 0 }
// llgo:link (*Cond).Destroy C.pthread_cond_destroy
func (c *Cond) Destroy() {}
// llgo:link (*Cond).Signal C.pthread_cond_signal
func (c *Cond) Signal() c.Int { return 0 }
// llgo:link (*Cond).Broadcast C.pthread_cond_broadcast
func (c *Cond) Broadcast() c.Int { return 0 }
// llgo:link (*Cond).Wait C.pthread_cond_wait
func (c *Cond) Wait(m *Mutex) c.Int { return 0 }
// llgo:link (*Cond).TimedWait C.pthread_cond_timedwait
func (c *Cond) TimedWait(m *Mutex, abstime *time.Timespec) c.Int { return 0 }
// -----------------------------------------------------------------------------

View File

@@ -0,0 +1,18 @@
package main
import (
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/raylib"
)
func main() {
const screenWidth = 800
const screenHeight = 450
raylib.InitWindow(screenWidth, screenHeight, c.Str("Raylib DEMO"))
for !raylib.WindowShouldClose() {
raylib.BeginDrawing()
raylib.ClearBackground(raylib.RAYWHITE)
raylib.DrawRectangle(screenWidth/2-50, screenHeight/2-50, 100, 100, raylib.BLUE)
raylib.EndDrawing()
}
}

View File

@@ -0,0 +1,181 @@
package main
import (
"unsafe"
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/raylib"
)
const (
BOARD_WIDTH = 10
BOARD_HEIGHT = 20
BLOCK_SIZE = 30
SCREENWIDTH = 300
SCREENHEIGHT = 600
)
const MAX_BLOCKS = 4
type Shape struct {
Blocks [MAX_BLOCKS]raylib.Vector2
Color raylib.Color
}
var SHAPES = []Shape{
{Blocks: [MAX_BLOCKS]raylib.Vector2{{X: 0, Y: 0}, {X: 1, Y: 0}, {X: 2, Y: 0}, {X: 3, Y: 0}}, Color: raylib.SKYBLUE},
{Blocks: [MAX_BLOCKS]raylib.Vector2{{X: 0, Y: 0}, {X: 1, Y: 0}, {X: 0, Y: 1}, {X: 1, Y: 1}}, Color: raylib.YELLOW},
{Blocks: [MAX_BLOCKS]raylib.Vector2{{X: 1, Y: 0}, {X: 0, Y: 1}, {X: 1, Y: 1}, {X: 2, Y: 1}}, Color: raylib.PURPLE},
{Blocks: [MAX_BLOCKS]raylib.Vector2{{X: 1, Y: 0}, {X: 2, Y: 0}, {X: 0, Y: 1}, {X: 1, Y: 1}}, Color: raylib.GREEN},
{Blocks: [MAX_BLOCKS]raylib.Vector2{{X: 0, Y: 0}, {X: 1, Y: 0}, {X: 1, Y: 1}, {X: 2, Y: 1}}, Color: raylib.RED},
{Blocks: [MAX_BLOCKS]raylib.Vector2{{X: 0, Y: 0}, {X: 0, Y: 1}, {X: 1, Y: 1}, {X: 2, Y: 1}}, Color: raylib.BLUE},
{Blocks: [MAX_BLOCKS]raylib.Vector2{{X: 2, Y: 0}, {X: 0, Y: 1}, {X: 1, Y: 1}, {X: 2, Y: 1}}, Color: raylib.ORANGE},
}
var board [BOARD_HEIGHT][BOARD_WIDTH]raylib.Color
var curShape Shape
var curPos raylib.Vector2
var fallTime = c.Float(0)
var fallSpeed = c.Float(0.2)
var score = 0
var scoreText = make([]c.Char, 20)
var gameOver = false
func genShape() {
curShape = SHAPES[raylib.GetRandomValue(c.Int(0), c.Int(6))]
curPos = raylib.Vector2{BOARD_WIDTH/2 - 1, 0}
}
func checkCollision() bool {
for i := 0; i < MAX_BLOCKS; i++ {
x := int(curPos.X + curShape.Blocks[i].X)
y := int(curPos.Y + curShape.Blocks[i].Y)
if x < 0 || x >= BOARD_WIDTH || y >= BOARD_HEIGHT || (y >= 0 && board[y][x] != raylib.BLANK) {
return true
}
}
return false
}
func lockShape() {
for i := 0; i < MAX_BLOCKS; i++ {
x := int(curPos.X + curShape.Blocks[i].X)
y := int(curPos.Y + curShape.Blocks[i].Y)
if y >= 0 {
board[y][x] = curShape.Color
}
}
}
func rotateShape() {
rotated := curShape
for i := 0; i < MAX_BLOCKS; i++ {
x := rotated.Blocks[i].X
rotated.Blocks[i].X = -rotated.Blocks[i].Y
rotated.Blocks[i].Y = x
}
temp := curShape
curShape = rotated
if checkCollision() {
curShape = temp
}
}
func clearLines() int {
linesCleared := 0
for y := BOARD_HEIGHT - 1; y >= 0; y-- {
lineFull := true
for x := 0; x < BOARD_WIDTH; x++ {
if board[y][x] == raylib.BLANK {
lineFull = false
break
}
}
if lineFull {
for yy := y; yy > 0; yy-- {
for x := 0; x < BOARD_WIDTH; x++ {
board[yy][x] = board[yy-1][x]
}
}
for x := 0; x < BOARD_WIDTH; x++ {
board[0][x] = raylib.BLANK
}
y += 1
linesCleared += 1
}
}
return linesCleared
}
func keyPressed(key c.Int) bool {
return raylib.IsKeyPressed(key) || raylib.IsKeyPressedRepeat(key)
}
func main() {
raylib.InitWindow(SCREENWIDTH, SCREENHEIGHT, c.Str("tetris (powered by raylib + llgo)"))
raylib.SetTargetFPS(c.Int(60))
genShape()
for !raylib.WindowShouldClose() && !gameOver {
fallTime += raylib.GetFrameTime()
if fallTime >= fallSpeed {
fallTime = 0
curPos.Y += 1
if checkCollision() {
curPos.Y -= 1
lockShape()
linesCleared := clearLines()
score += linesCleared * 100
genShape()
if checkCollision() {
gameOver = true
}
}
}
if keyPressed(raylib.KEY_LEFT) {
curPos.X -= 1
if checkCollision() {
curPos.X += 1
}
}
if keyPressed(raylib.KEY_RIGHT) {
curPos.X += 1
if checkCollision() {
curPos.X -= 1
}
}
if keyPressed(raylib.KEY_SPACE) || keyPressed(raylib.KEY_UP) || keyPressed(raylib.KEY_DOWN) {
rotateShape()
}
raylib.BeginDrawing()
raylib.ClearBackground(raylib.RAYWHITE)
for y := 0; y < BOARD_HEIGHT; y++ {
for x := 0; x < BOARD_WIDTH; x++ {
raylib.DrawRectangle(c.Int(x*BLOCK_SIZE), c.Int(y*BLOCK_SIZE), c.Int(BLOCK_SIZE-1), c.Int(BLOCK_SIZE-1), board[y][x])
}
}
for i := 0; i < MAX_BLOCKS; i++ {
raylib.DrawRectangle(c.Int((curPos.X+curShape.Blocks[i].X)*BLOCK_SIZE), c.Int((curPos.Y+curShape.Blocks[i].Y)*BLOCK_SIZE),
BLOCK_SIZE-1, BLOCK_SIZE-1, curShape.Color)
}
c.Sprintf(unsafe.SliceData(scoreText), c.Str("Score:%d"), score)
raylib.DrawText(unsafe.SliceData(scoreText), 10, 10, 20, raylib.BLACK)
raylib.EndDrawing()
}
for !raylib.WindowShouldClose() {
raylib.BeginDrawing()
raylib.ClearBackground(raylib.RAYWHITE)
raylib.DrawText(c.Str("Game Over"), SCREENWIDTH/2-50, SCREENHEIGHT/2-10, 20, raylib.RED)
raylib.DrawText(unsafe.SliceData(scoreText), SCREENWIDTH/2-50, SCREENHEIGHT/2+10, 20, raylib.BLACK)
raylib.EndDrawing()
}
}

BIN
c/raylib/llgo_autogen.lla Normal file

Binary file not shown.

485
c/raylib/raylib.go Normal file
View File

@@ -0,0 +1,485 @@
/*
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package raylib
import (
_ "unsafe"
"github.com/goplus/llgo/c"
)
const (
LLGoPackage = "link: $(pkg-config --libs raylib); -lraylib"
)
// -----------------------------------------------------------------------------
// Vector2, 2 components
type Vector2 struct {
X float32 // Vector x component
Y float32 // Vector y component
}
// Vector3, 3 components
type Vector3 struct {
X float32 // Vector x component
Y float32 // Vector y component
Z float32 // Vector z component
}
// Vector4, 4 components
type Vector4 struct {
X float32 // Vector x component
Y float32 // Vector y component
Z float32 // Vector z component
W float32 // Vector w component
}
// Quaternion, 4 components (Vector4 alias)
type Quaternion = Vector4
//----------------------------------------------------------------------------------
// Enumerators Definition
// System/Window config flags
// By default all flags are set to 0
// Trace log level
// Keyboard keys (US keyboard layout)
// required keys for alternative layouts
const (
KEY_NULL = 0 // Key: NULL, used for no key pressed
// Alphanumeric keys
KEY_APOSTROPHE = 39 // Key: '
KEY_COMMA = 44 // Key: ,
KEY_MINUS = 45 // Key: -
KEY_PERIOD = 46 // Key: .
KEY_SLASH = 47 // Key: /
KEY_ZERO = 48 // Key: 0
KEY_ONE = 49 // Key: 1
KEY_TWO = 50 // Key: 2
KEY_THREE = 51 // Key: 3
KEY_FOUR = 52 // Key: 4
KEY_FIVE = 53 // Key: 5
KEY_SIX = 54 // Key: 6
KEY_SEVEN = 55 // Key: 7
KEY_EIGHT = 56 // Key: 8
KEY_NINE = 57 // Key: 9
KEY_SEMICOLON = 59 // Key: ;
KEY_EQUAL = 61 // Key: =
KEY_A = 65 // Key: A | a
KEY_B = 66 // Key: B | b
KEY_C = 67 // Key: C | c
KEY_D = 68 // Key: D | d
KEY_E = 69 // Key: E | e
KEY_F = 70 // Key: F | f
KEY_G = 71 // Key: G | g
KEY_H = 72 // Key: H | h
KEY_I = 73 // Key: I | i
KEY_J = 74 // Key: J | j
KEY_K = 75 // Key: K | k
KEY_L = 76 // Key: L | l
KEY_M = 77 // Key: M | m
KEY_N = 78 // Key: N | n
KEY_O = 79 // Key: O | o
KEY_P = 80 // Key: P | p
KEY_Q = 81 // Key: Q | q
KEY_R = 82 // Key: R | r
KEY_S = 83 // Key: S | s
KEY_T = 84 // Key: T | t
KEY_U = 85 // Key: U | u
KEY_V = 86 // Key: V | v
KEY_W = 87 // Key: W | w
KEY_X = 88 // Key: X | x
KEY_Y = 89 // Key: Y | y
KEY_Z = 90 // Key: Z | z
KEY_LEFT_BRACKET = 91 // Key: [
KEY_BACKSLASH = 92 // Key: '\'
KEY_RIGHT_BRACKET = 93 // Key: ]
KEY_GRAVE = 96 // Key: `
// Function keys
KEY_SPACE = 32 // Key: Space
KEY_ESCAPE = 256 // Key: Esc
KEY_ENTER = 257 // Key: Enter
KEY_TAB = 258 // Key: Tab
KEY_BACKSPACE = 259 // Key: Backspace
KEY_INSERT = 260 // Key: Ins
KEY_DELETE = 261 // Key: Del
KEY_RIGHT = 262 // Key: Cursor right
KEY_LEFT = 263 // Key: Cursor left
KEY_DOWN = 264 // Key: Cursor down
KEY_UP = 265 // Key: Cursor up
KEY_PAGE_UP = 266 // Key: Page up
KEY_PAGE_DOWN = 267 // Key: Page down
KEY_HOME = 268 // Key: Home
KEY_END = 269 // Key: End
KEY_CAPS_LOCK = 280 // Key: Caps lock
KEY_SCROLL_LOCK = 281 // Key: Scroll down
KEY_NUM_LOCK = 282 // Key: Num lock
KEY_PRINT_SCREEN = 283 // Key: Print screen
KEY_PAUSE = 284 // Key: Pause
KEY_F1 = 290 // Key: F1
KEY_F2 = 291 // Key: F2
KEY_F3 = 292 // Key: F3
KEY_F4 = 293 // Key: F4
KEY_F5 = 294 // Key: F5
KEY_F6 = 295 // Key: F6
KEY_F7 = 296 // Key: F7
KEY_F8 = 297 // Key: F8
KEY_F9 = 298 // Key: F9
KEY_F10 = 299 // Key: F10
KEY_F11 = 300 // Key: F11
KEY_F12 = 301 // Key: F12
KEY_LEFT_SHIFT = 340 // Key: Shift left
KEY_LEFT_CONTROL = 341 // Key: Control left
KEY_LEFT_ALT = 342 // Key: Alt left
KEY_LEFT_SUPER = 343 // Key: Super left
KEY_RIGHT_SHIFT = 344 // Key: Shift right
KEY_RIGHT_CONTROL = 345 // Key: Control right
KEY_RIGHT_ALT = 346 // Key: Alt right
KEY_RIGHT_SUPER = 347 // Key: Super right
KEY_KB_MENU = 348 // Key: KB menu
// Keypad keys
KEY_KP_0 = 320 // Key: Keypad 0
KEY_KP_1 = 321 // Key: Keypad 1
KEY_KP_2 = 322 // Key: Keypad 2
KEY_KP_3 = 323 // Key: Keypad 3
KEY_KP_4 = 324 // Key: Keypad 4
KEY_KP_5 = 325 // Key: Keypad 5
KEY_KP_6 = 326 // Key: Keypad 6
KEY_KP_7 = 327 // Key: Keypad 7
KEY_KP_8 = 328 // Key: Keypad 8
KEY_KP_9 = 329 // Key: Keypad 9
KEY_KP_DECIMAL = 330 // Key: Keypad .
KEY_KP_DIVIDE = 331 // Key: Keypad /
KEY_KP_MULTIPLY = 332 // Key: Keypad *
KEY_KP_SUBTRACT = 333 // Key: Keypad -
KEY_KP_ADD = 334 // Key: Keypad +
KEY_KP_ENTER = 335 // Key: Keypad Enter
KEY_KP_EQUAL = 336 // Key: Keypad =
// Android key buttons
KEY_BACK = 4 // Key: Android back button
KEY_MENU = 82 // Key: Android menu button
KEY_VOLUME_UP = 24 // Key: Android volume up button
KEY_VOLUME_DOWN = 25 // Key: Android volume down button
)
// Mouse buttons
// Mouse cursor
// Gamepad buttons
// Gamepad axis
// Material map index
// Shader location index
// Shader uniform data type
// Shader attribute data types
// Pixel formats
// Texture parameters: filter mode
// Texture parameters: wrap mode
// Cubemap layouts
// Font type, defines generation method
// Color blending modes (pre-defined)
// Gesture
// Camera system modes
// Camera projection
// N-patch layout
// -----------------------------------------------------------------------------
// Window-related functions
//go:linkname InitWindow C.InitWindow
func InitWindow(width, height c.Int, title *c.Char)
//go:linkname CloseWindow C.CloseWindow
func CloseWindow()
//go:linkname WindowShouldClose C.WindowShouldClose
func WindowShouldClose() bool
//go:linkname IsWindowReady C.IsWindowReady
func IsWindowReady() bool
//go:linkname IsWindowFullscreen C.IsWindowFullscreen
func IsWindowFullscreen() bool
//go:linkname IsWindowHidden C.IsWindowHidden
func IsWindowHidden() bool
//go:linkname IsWindowMinimized C.IsWindowMinimized
func IsWindowMinimized() bool
//go:linkname IsWindowMaximized C.IsWindowMaximized
func IsWindowMaximized() bool
//go:linkname IsWindowFocused C.IsWindowFocused
func IsWindowFocused() bool
//go:linkname IsWindowResized C.IsWindowResized
func IsWindowResized() bool
//go:linkname IsWindowState C.IsWindowState
func IsWindowState(flag c.Int) bool
//go:linkname SetWindowState C.SetWindowState
func SetWindowState(flags c.Int)
//go:linkname ClearWindowState C.ClearWindowState
func ClearWindowState(flags c.Int)
//go:linkname ToggleFullscreen C.ToggleFullscreen
func ToggleFullscreen()
//go:linkname MaximizeWindow C.MaximizeWindow
func MaximizeWindow()
//go:linkname MinimizeWindow C.MinimizeWindow
func MinimizeWindow()
//go:linkname RestoreWindow C.RestoreWindow
func RestoreWindow()
//go:linkname SetWindowIcon C.SetWindowIcon
func SetWindowIcon(icon Image)
//go:linkname SetWindowIcons C.SetWindowIcons
func SetWindowIcons(icons *Image, count c.Int)
//go:linkname SetWindowTitle C.SetWindowTitle
func SetWindowTitle(title *c.Char)
//go:linkname SetWindowPosition C.SetWindowPosition
func SetWindowPosition(x, y c.Int)
//go:linkname SetWindowMonitor C.SetWindowMonitor
func SetWindowMonitor(monitor c.Int)
//go:linkname SetWindowMinSize C.SetWindowMinSize
func SetWindowMinSize(width, height c.Int)
//go:linkname SetWindowSize C.SetWindowSize
func SetWindowSize(width, height c.Int)
//go:linkname SetWindowOpacity C.SetWindowOpacity
func SetWindowOpacity(opacity c.Float)
//go:linkname SetWindowFocused C.SetWindowFocused
func SetWindowFocused()
//go:linkname GetWindowHandle C.GetWindowHandle
func GetWindowHandle() c.Pointer
//go:linkname GetScreenWidth C.GetScreenWidth
func GetScreenWidth() c.Int
//go:linkname GetScreenHeight C.GetScreenHeight
func GetScreenHeight() c.Int
// Get current render width (it considers HiDPI)
//
//go:linkname GetRenderWidth C.GetRenderWidth
func GetRenderWidth() c.Int
// Get current render height (it considers HiDPI)
//
//go:linkname GetRenderHeight C.GetRenderHeight
func GetRenderHeight() c.Int
// Get number of connected monitors
//
//go:linkname GetMonitorCount C.GetMonitorCount
func GetMonitorCount() c.Int
// Get current connected monitor
//
//go:linkname GetCurrentMonitor C.GetCurrentMonitor
func GetCurrentMonitor() c.Int
// Get specified monitor position
//
//go:linkname GetMonitorPosition C.GetMonitorPosition
func GetMonitorPosition(monitor c.Int) Vector2
//go:linkname GetMonitorWidth C.GetMonitorWidth
func GetMonitorWidth(monitor c.Int) c.Int
//go:linkname GetMonitorHeight C.GetMonitorHeight
func GetMonitorHeight(monitor c.Int) c.Int
//go:linkname GetMonitorPhysicalWidth C.GetMonitorPhysicalWidth
func GetMonitorPhysicalWidth(monitor c.Int) c.Int
//go:linkname GetMonitorPhysicalHeight C.GetMonitorPhysicalHeight
func GetMonitorPhysicalHeight(monitor c.Int) c.Int
//go:linkname GetMonitorRefreshRate C.GetMonitorRefreshRate
func GetMonitorRefreshRate(monitor c.Int) c.Int
//go:linkname GetWindowPosition C.GetWindowPosition
func GetWindowPosition() Vector2
//go:linkname GetWindowScaleDPI C.GetWindowScaleDPI
func GetWindowScaleDPI() Vector2
//go:linkname GetMonitorName C.GetMonitorName
func GetMonitorName(monitor c.Int) *c.Char
//go:linkname SetClipboardText C.SetClipboardText
func SetClipboardText(text *c.Char)
//go:linkname GetClipboardText C.GetClipboardText
func GetClipboardText() *c.Char
// Enable waiting for events on EndDrawing(), no automatic event polling
//
//go:linkname EnableEventWaiting C.EnableEventWaiting
func EnableEventWaiting()
// Disable waiting for events on EndDrawing(), automatic events polling
//
//go:linkname DisableEventWaiting C.DisableEventWaiting
func DisableEventWaiting()
// -----------------------------------------------------------------------------
// Cursor-related functions
//go:linkname ShowCursor C.ShowCursor
func ShowCursor()
//go:linkname HideCursor C.HideCursor
func HideCursor()
//go:linkname IsCursorHidden C.IsCursorHidden
func IsCursorHidden() bool
//go:linkname EnableCursor C.EnableCursor
func EnableCursor()
//go:linkname DisableCursor C.DisableCursor
func DisableCursor()
//go:linkname IsCursorOnScreen C.IsCursorOnScreen
func IsCursorOnScreen() bool
// -----------------------------------------------------------------------------
// Shader management functions
// -----------------------------------------------------------------------------
// Screen-space-related functions
// -----------------------------------------------------------------------------
// Timing-related functions
// Set target FPS (maximum)
//
//go:linkname SetTargetFPS C.SetTargetFPS
func SetTargetFPS(fps c.Int)
// Returns current FPS
//
//go:linkname GetFPS C.GetFPS
func GetFPS() c.Int
// Returns time in seconds for last frame drawn (delta time)
//
//go:linkname GetFrameTime C.GetFrameTime
func GetFrameTime() c.Float
// Returns elapsed time in seconds since InitWindow()
//
//go:linkname GetTime C.GetTime
func GetTime() c.Double
// -----------------------------------------------------------------------------
// Custom frame control functions
// NOTE: Those functions are intended for advance users that want full control over the frame processing
// By default EndDrawing() does this job: draws everything + SwapScreenBuffer() + manage frame timing + PollInputEvents()
// To avoid that behaviour and control frame processes manually, enable in config.h: SUPPORT_CUSTOM_FRAME_CONTROL
// -----------------------------------------------------------------------------
// Random values generation functions
//go:linkname SetRandomSeed C.SetRandomSeed
func SetRandomSeed(seed c.Uint)
//go:linkname GetRandomValue C.GetRandomValue
func GetRandomValue(min c.Int, max c.Int) c.Int
// -----------------------------------------------------------------------------
// Misc. functions
// -----------------------------------------------------------------------------
// Input-related functions: keyboard
//go:linkname IsKeyPressed C.IsKeyPressed
func IsKeyPressed(key c.Int) bool
//go:linkname IsKeyPressedRepeat C.IsKeyPressedRepeat
func IsKeyPressedRepeat(key c.Int) bool
//go:linkname IsKeyDown C.IsKeyDown
func IsKeyDown(key c.Int) bool
//go:linkname IsKeyReleased C.IsKeyReleased
func IsKeyReleased(key c.Int) bool
//go:linkname IsKeyUp C.IsKeyUp
func IsKeyUp(key c.Int) bool
//go:linkname GetKeyPressed C.GetKeyPressed
func GetKeyPressed() c.Int
//go:linkname GetCharPressed C.GetCharPressed
func GetCharPressed() c.Int
//go:linkname SetExitKey C.SetExitKey
func SetExitKey(key c.Int)
// -----------------------------------------------------------------------------
// Input-related functions: gamepads
// -----------------------------------------------------------------------------
// Input-related functions: mouse
// -----------------------------------------------------------------------------
// Input-related functions: touch
// -----------------------------------------------------------------------------
// Gestures and Touch Handling Functions (Module: rgestures)
// -----------------------------------------------------------------------------

215
c/raylib/shape.go Normal file
View File

@@ -0,0 +1,215 @@
/*
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package raylib
import (
_ "unsafe"
"github.com/goplus/llgo/c"
)
// -----------------------------------------------------------------------------
// Color, 4 components, R8G8B8A8 (32bit)
// R, G, B, A uint8
type Color uint32
const (
LIGHTGRAY = Color(200 | 200<<8 | 200<<16 | 255<<24) // Light Gray
GRAY = Color(130 | 130<<8 | 130<<16 | 255<<24) // Gray
DARKGRAY = Color(80 | 80<<8 | 80<<16 | 255<<24) // Dark Gray
YELLOW = Color(253 | 249<<8 | 0<<16 | 255<<24) // Yellow
GOLD = Color(255 | 203<<8 | 0<<16 | 255<<24) // Gold
ORANGE = Color(255 | 161<<8 | 0<<16 | 255<<24) // Orange
PINK = Color(255 | 109<<8 | 194<<16 | 255<<24) // Pink
RED = Color(230 | 41<<8 | 55<<16 | 255<<24) // Red
MAROON = Color(190 | 33<<8 | 55<<16 | 255<<24) // Maroon
GREEN = Color(0 | 228<<8 | 48<<16 | 255<<24) // Green
LIME = Color(0 | 158<<8 | 47<<16 | 255<<24) // Lime
DARKGREEN = Color(0 | 117<<8 | 44<<16 | 255<<24) // Dark Green
SKYBLUE = Color(102 | 191<<8 | 255<<16 | 255<<24) // Sky Blue
BLUE = Color(0 | 121<<8 | 241<<16 | 255<<24) // Blue
DARKBLUE = Color(0 | 82<<8 | 172<<16 | 255<<24) // Dark Blue
PURPLE = Color(200 | 122<<8 | 255<<16 | 255<<24) // Purple
VIOLET = Color(135 | 60<<8 | 190<<16 | 255<<24) // Violet
DARKPURPLE = Color(112 | 31<<8 | 126<<16 | 255<<24) // Dark Purple
BEIGE = Color(211 | 176<<8 | 131<<16 | 255<<24) // Beige
BROWN = Color(127 | 106<<8 | 79<<16 | 255<<24) // Brown
DARKBROWN = Color(76 | 63<<8 | 47<<16 | 255<<24) // Dark Brown
WHITE = Color(255 | 255<<8 | 255<<16 | 255<<24) // White
BLACK = Color(0 | 0<<8 | 0<<16 | 255<<24) // Black
BLANK = Color(0 | 0<<8 | 0<<16 | 0<<24) // Blank (Transparent)
MAGENTA = Color(255 | 0<<8 | 255<<16 | 255<<24) // Magenta
RAYWHITE = Color(245 | 245<<8 | 245<<16 | 255<<24) // My own White (raylib logo)
)
// Image, pixel data stored in CPU memory (RAM)
type Image struct {
Data c.Pointer // Image raw data
Width c.Int // Image base width
Height c.Int // Image base height
Mipmaps c.Int // Mipmap levels, 1 by default
Format c.Int // Data format (PixelFormat type)
}
// Camera, defines position/orientation in 3d space
type Camera3D struct {
Position Vector3 // Camera position
Target Vector3 // Camera target it looks-at
Up Vector3 // Camera up vector (rotation over its axis)
Fovy float32 // Camera field-of-view aperture in Y (degrees) in perspective, used as near plane width in orthographic
Projection c.Int // Camera projection: CAMERA_PERSPECTIVE or CAMERA_ORTHOGRAPHIC
}
type Camera = Camera3D // Camera type fallback, defaults to Camera3D
// Camera2D, defines position/orientation in 2d space
type Camera2D struct {
Offset Vector2 // Camera offset (displacement from target)
Target Vector2 // Camera target (rotation and zoom origin)
Rotation float32 // Camera rotation in degrees
Zoom float32 // Camera zoom (scaling), should be 1.0f by default
}
// Shader
type Shader struct {
Id c.Uint // Shader program id
Locs *c.Int // Shader locations array (RL_MAX_SHADER_LOCATIONS)
}
// -----------------------------------------------------------------------------
// Drawing-related functions
// Set background color (framebuffer clear color)
//
//go:linkname ClearBackground C.ClearBackground
func ClearBackground(color Color)
// Begin drawing (call before drawing anything)
//
//go:linkname BeginDrawing C.BeginDrawing
func BeginDrawing()
// End drawing and swap buffers (call after drawing)
//
//go:linkname EndDrawing C.EndDrawing
func EndDrawing()
// Begin 2D mode with custom camera (2D)
//
//go:linkname BeginMode2D C.BeginMode2D
func BeginMode2D(camera Camera2D)
// End mode (2D)
//
//go:linkname EndMode2D C.EndMode2D
func EndMode2D()
// Begin 3D mode with custom camera (3D)
//
//go:linkname BeginMode3D C.BeginMode3D
func BeginMode3D(camera Camera3D)
// End mode (3D)
//
//go:linkname EndMode3D C.EndMode3D
func EndMode3D()
// Begin drawing to render texture
//-go:linkname BeginTextureMode C.BeginTextureMode
//func BeginTextureMode(target RenderTexture2D)
// End drawing to render texture
//
//go:linkname EndTextureMode C.EndTextureMode
func EndTextureMode()
// Begin custom shader drawing
//
//go:linkname BeginShaderMode C.BeginShaderMode
func BeginShaderMode(shader Shader)
// End custom shader drawing (use default shader)
//
//go:linkname EndShaderMode C.EndShaderMode
func EndShaderMode()
// Color blending modes (pre-defined)
type BlendMode c.Int
const (
BLEND_ALPHA BlendMode = iota // Blend textures considering alpha (default)
BLEND_ADDITIVE // Blend textures adding colors
BLEND_MULTIPLIED // Blend textures multiplying colors
BLEND_ADD_COLORS // Blend textures adding colors (alternative)
BLEND_SUBTRACT_COLORS // Blend textures subtracting colors (alternative)
BLEND_ALPHA_PREMULTIPLY // Blend premultiplied textures considering alpha
BLEND_CUSTOM // Blend textures using custom src/dst factors (use rlSetBlendFactors())
BLEND_CUSTOM_SEPARATE // Blend textures using custom rgb/alpha separate src/dst factors (use rlSetBlendFactorsSeparate())
)
// Begin blending mode (alpha, additive, multiplied, subtract, custom)
//
//go:linkname BeginBlendMode C.BeginBlendMode
func BeginBlendMode(mode BlendMode)
// End blending mode (reset to default: alpha blending)
//
//go:linkname EndBlendMode C.EndBlendMode
func EndBlendMode()
// Begin scissor mode (define screen area for following drawing)
//
//go:linkname BeginScissorMode C.BeginScissorMode
func BeginScissorMode(x, y, width, height c.Int)
// End scissor mode
//
//go:linkname EndScissorMode C.EndScissorMode
func EndScissorMode()
// -----------------------------------------------------------------------------
// VR stereo config functions for VR simulator
// -----------------------------------------------------------------------------
// Camera System Functions (Module: rcamera)
// Update camera position for selected mode
//
//go:linkname UpdateCamera C.UpdateCamera
func UpdateCamera(camera *Camera, mode c.Int)
// Update camera movement/rotation
//
//go:linkname UpdateCameraPro C.UpdateCameraPro
func UpdateCameraPro(camera *Camera, movement, rotation Vector3, zoom float32)
// -----------------------------------------------------------------------------
// Draw a color-filled rectangle
//
//go:linkname DrawRectangle C.DrawRectangle
func DrawRectangle(posX, posY, width, height c.Int, color Color)
// Draw text (using default font)
//
//go:linkname DrawText C.DrawText
func DrawText(text *c.Char, posX, posY, fontSize c.Int, color Color)
// -----------------------------------------------------------------------------

67
c/raylib/utils.go Normal file
View File

@@ -0,0 +1,67 @@
/*
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package raylib
import (
_ "unsafe"
"github.com/goplus/llgo/c"
)
// -----------------------------------------------------------------------------
// Show trace log messages (LOG_DEBUG, LOG_INFO, LOG_WARNING, LOG_ERROR...)
//
//go:linkname TraceLog C.TraceLog
func TraceLog(logLevel int, text *c.Char, __llgo_va_list ...any)
// Set the current threshold (minimum) log level
//
//go:linkname SetTraceLogLevel C.SetTraceLogLevel
func SetTraceLogLevel(logLevel int)
// -----------------------------------------------------------------------------
// Set custom callbacks
// -----------------------------------------------------------------------------
// Files management functions
// -----------------------------------------------------------------------------
// File system functions
// Check if file exists
//
//go:linkname FileExists C.FileExists
func FileExists(fileName *c.Char) bool
// Check if a directory path exists
//
//go:linkname DirectoryExists C.DirectoryExists
func DirectoryExists(dirPath *c.Char) bool
// Check file extension (including point: .png, .wav)
//
//go:linkname IsFileExtension C.IsFileExtension
func IsFileExtension(fileName *c.Char, ext *c.Char) bool
// -----------------------------------------------------------------------------
// Compression/Encoding functionality
// -----------------------------------------------------------------------------
// Automation events functionality
// -----------------------------------------------------------------------------

53
c/setjmp/setjmp.go Normal file
View File

@@ -0,0 +1,53 @@
/*
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package setjmp
// #include <setjmp.h>
import "C"
import (
_ "unsafe"
"github.com/goplus/llgo/c"
)
const (
LLGoPackage = "decl"
)
type (
JmpBuf = C.jmp_buf
SigjmpBuf = C.sigjmp_buf
)
// -----------------------------------------------------------------------------
//go:linkname Setjmp C.setjmp
func Setjmp(env *JmpBuf) c.Int
//go:linkname Longjmp C.longjmp
func Longjmp(env *JmpBuf, val c.Int)
// -----------------------------------------------------------------------------
//go:linkname Sigsetjmp C.sigsetjmp
func Sigsetjmp(env *SigjmpBuf, savemask c.Int) c.Int
//go:linkname Siglongjmp C.siglongjmp
func Siglongjmp(env *SigjmpBuf, val c.Int)
// -----------------------------------------------------------------------------

View File

@@ -0,0 +1,5 @@
#include <stdexcept>
extern "C" void throwCppException() {
throw std::runtime_error("C++ exception");
}

View File

@@ -0,0 +1,13 @@
#include <exception>
#include <stdio.h>
extern "C" void throwCppException();
int main() {
try {
throwCppException();
} catch (std::exception& e) {
printf("Hi, %s\n", e.what());
}
return 0;
}

28
c/setjmp/trycatch/demo.go Normal file
View File

@@ -0,0 +1,28 @@
/*
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package trycatch
import (
_ "unsafe"
)
const (
LLGoPackage = "link: c++"
)
//go:linkname ThrowCppException C.throwCppException
func ThrowCppException()

View File

@@ -0,0 +1,8 @@
{
"cl": [
"clang -emit-llvm -S -o demo.ll -c _code/demo.cpp",
"clang -emit-llvm -S -o _code/llgo_autogen.ll -c _code/try_catch.cpp",
"llgen .",
"rm llgo_autogen.lla; zip llgo_autogen.lla llgo_autogen.ll demo.ll",
]
}

Binary file not shown.

View File

@@ -1,22 +1,18 @@
LLGo wrapper of sqlite
=====
[![Build Status](https://github.com/goplus/sqlite/actions/workflows/go.yml/badge.svg)](https://github.com/goplus/sqlite/actions/workflows/go.yml)
[![GitHub release](https://img.shields.io/github/v/tag/goplus/sqlite.svg?label=release)](https://github.com/goplus/sqlite/releases)
[![GoDoc](https://pkg.go.dev/badge/github.com/goplus/sqlite.svg)](https://pkg.go.dev/github.com/goplus/sqlite)
[![Compiler](https://img.shields.io/badge/compiler-llgo-darkgreen.svg)](https://github.com/goplus/llgo)
[![Language](https://img.shields.io/badge/language-Go+-blue.svg)](https://github.com/goplus/gop)
## How to install
### on macOS (Homebrew)
```sh
git clone https://github.com/goplus/sqlite.git
cd sqlite
git submodule init
git submodule update
mkdir build.dir
cd build.dir
../sqlite/configure --enable-shared
sudo make install
brew install sqlite3
```
### on Linux (Debian/Ubuntu)
```sh
apt-get install -y libsqlite3-dev
```
## Demos

View File

@@ -2,11 +2,12 @@ package main
import (
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/os"
"github.com/goplus/llgo/c/sqlite"
)
func main() {
c.Remove(c.Str("test.db"))
os.Remove(c.Str("test.db"))
db, err := sqlite.Open(c.Str("test.db"))
check(err, db, "sqlite: Open")

Binary file not shown.

View File

@@ -23,7 +23,7 @@ import (
)
const (
LLGoPackage = "link: sqlite3"
LLGoPackage = "link: $(pkg-config --libs sqlite3); -lsqlite3"
)
// llgo:type C

72
c/sync/atomic/atomic.go Normal file
View File

@@ -0,0 +1,72 @@
/*
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package atomic
import (
"unsafe"
_ "unsafe"
)
const (
LLGoPackage = "decl"
)
type valtype interface {
~int | ~uint | ~uintptr | ~int32 | ~uint32 | ~int64 | ~uint64 | ~unsafe.Pointer
}
// llgo:link Add llgo.atomicAdd
func Add[T valtype](ptr *T, v T) T { return v }
// llgo:link Sub llgo.atomicSub
func Sub[T valtype](ptr *T, v T) T { return v }
// llgo:link And llgo.atomicAnd
func And[T valtype](ptr *T, v T) T { return v }
// llgo:link NotAnd llgo.atomicNand
func NotAnd[T valtype](ptr *T, v T) T { return v }
// llgo:link Or llgo.atomicOr
func Or[T valtype](ptr *T, v T) T { return v }
// llgo:link Xor llgo.atomicXor
func Xor[T valtype](ptr *T, v T) T { return v }
// llgo:link Max llgo.atomicMax
func Max[T valtype](ptr *T, v T) T { return v }
// llgo:link Min llgo.atomicMin
func Min[T valtype](ptr *T, v T) T { return v }
// llgo:link UMax llgo.atomicUMax
func UMax[T valtype](ptr *T, v T) T { return v }
// llgo:link UMin llgo.atomicUMin
func UMin[T valtype](ptr *T, v T) T { return v }
// llgo:link Load llgo.atomicLoad
func Load[T valtype](ptr *T) T { return *ptr }
// llgo:link Store llgo.atomicStore
func Store[T valtype](ptr *T, v T) {}
// llgo:link Exchange llgo.atomicXchg
func Exchange[T valtype](ptr *T, v T) T { return v }
// llgo:link CompareAndExchange llgo.atomicCmpXchg
func CompareAndExchange[T valtype](ptr *T, old, new T) (T, bool) { return old, false }

132
c/time/time.go Normal file
View File

@@ -0,0 +1,132 @@
/*
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package time
// #include <time.h>
import "C"
import (
_ "unsafe"
"github.com/goplus/llgo/c"
)
const (
LLGoPackage = "decl"
)
// -----------------------------------------------------------------------------
type TimeT C.time_t
//go:linkname Time C.time
func Time(timer *TimeT) TimeT
//go:linkname Mktime C.mktime
func Mktime(timer *Tm) TimeT
//go:linkname Ctime C.ctime
func Ctime(timer *TimeT) string
//go:linkname Difftime C.difftime
func Difftime(end, start TimeT) float64
// -----------------------------------------------------------------------------
type Tm struct {
Sec c.Int
Min c.Int
Hour c.Int
Mday c.Int
Mon c.Int
Year c.Int
Wday c.Int
Yday c.Int
Isdst c.Int
Gmtoff c.Long
Zone *c.Char
}
//go:linkname Gmtime C.gmtime
func Gmtime(timer *TimeT) *Tm
//go:linkname Localtime C.localtime
func Localtime(timer *TimeT) *Tm
//go:linkname Strftime C.strftime
func Strftime(buf *c.Char, bufSize uintptr, format *c.Char, timeptr *Tm) uintptr
// -----------------------------------------------------------------------------
type ClockT C.clock_t
//go:linkname Clock C.clock
func Clock() ClockT
// -----------------------------------------------------------------------------
type ClockidT C.clockid_t
const (
// the system's real time (i.e. wall time) clock, expressed as the amount of time since the Epoch.
// This is the same as the value returned by gettimeofday
CLOCK_REALTIME = ClockidT(C.CLOCK_REALTIME)
// clock that increments monotonically, tracking the time since an arbitrary point, and will continue
// to increment while the system is asleep.
CLOCK_MONOTONIC = ClockidT(C.CLOCK_MONOTONIC)
// clock that increments monotonically, tracking the time since an arbitrary point like CLOCK_MONOTONIC.
// However, this clock is unaffected by frequency or time adjustments. It should not be compared to
// other system time sources.
CLOCK_MONOTONIC_RAW = ClockidT(C.CLOCK_MONOTONIC_RAW)
// like CLOCK_MONOTONIC_RAW, but reads a value cached by the system at context switch. This can be
// read faster, but at a loss of accuracy as it may return values that are milliseconds old.
// CLOCK_MONOTONIC_RAW_APPROX = ClockidT(C.CLOCK_MONOTONIC_RAW_APPROX)
// clock that increments monotonically, in the same manner as CLOCK_MONOTONIC_RAW, but that does
// not increment while the system is asleep. The returned value is identical to the result of
// mach_absolute_time() after the appropriate mach_timebase conversion is applied.
// CLOCK_UPTIME_RAW = ClockidT(C.CLOCK_UPTIME_RAW)
// like CLOCK_UPTIME_RAW, but reads a value cached by the system at context switch. This can be read
// faster, but at a loss of accuracy as it may return values that are milliseconds old.
// CLOCK_UPTIME_RAW_APPROX = ClockidT(C.CLOCK_UPTIME_RAW_APPROX)
// clock that tracks the amount of CPU (in user- or kernel-mode) used by the calling process.
CLOCK_PROCESS_CPUTIME_ID = ClockidT(C.CLOCK_PROCESS_CPUTIME_ID)
// clock that tracks the amount of CPU (in user- or kernel-mode) used by the calling thread.
CLOCK_THREAD_CPUTIME_ID = ClockidT(C.CLOCK_THREAD_CPUTIME_ID)
)
type Timespec struct {
Sec TimeT // seconds
Nsec c.Long // and nanoseconds
}
//go:linkname ClockGettime C.clock_gettime
func ClockGettime(clkId ClockidT, tp *Timespec) c.Int
//go:linkname ClockSettime C.clock_settime
func ClockSettime(clkId ClockidT, tp *Timespec) c.Int
//go:linkname ClockGetres C.clock_getres
func ClockGetres(clkId ClockidT, res *Timespec) c.Int
// -----------------------------------------------------------------------------

View File

@@ -0,0 +1,35 @@
package main
import (
"unsafe"
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/zlib"
)
func main() {
txt := []byte("zlib is a software library used for data compression. It was created by Jean-loup Gailly and Mark Adler and first released in 1995. zlib is designed to be a free, legally unencumbered—that is, not covered by any patents—alternative to the proprietary DEFLATE compression algorithm, which is often used in software applications for data compression.The library provides functions to compress and decompress data using the DEFLATE algorithm, which is a combination of the LZ77 algorithm and Huffman coding. zlib is notable for its versatility; it can be used in a wide range of applications, from web servers and web clients compressing HTTP data, to the compression of data for storage or transmission in various file formats, such as PNG, ZIP, and GZIP.")
txtLen := c.Ulong(len(txt))
for level := 0; level <= 9; level++ {
cmpSize := zlib.CompressBound(txtLen)
cmpData := make([]byte, int(cmpSize))
res := zlib.Compress2(unsafe.SliceData(cmpData), &cmpSize, unsafe.SliceData(txt), txtLen, c.Int(level))
if res != zlib.OK {
c.Printf(c.Str("\nCompression failed at level %d: %d\n"), level, res)
continue
}
c.Printf(c.Str("Compression level %d: Text length = %d, Compressed size = %d\n"), level, txtLen, cmpSize)
ucmpSize := txtLen
ucmpData := make([]byte, int(ucmpSize))
unRes := zlib.Uncompress(unsafe.SliceData(ucmpData), &ucmpSize, unsafe.SliceData(cmpData), cmpSize)
if unRes != zlib.OK {
c.Printf(c.Str("\nDecompression failed at level %d: %d\n"), level, unRes)
continue
}
}
}

View File

@@ -0,0 +1,46 @@
package main
import (
"unsafe"
"github.com/goplus/llgo/c"
"github.com/goplus/llgo/c/zlib"
)
func main() {
txt := []byte("zlib is a software library used for data compression. It was created by Jean-loup Gailly and Mark Adler and first released in 1995. zlib is designed to be a free, legally unencumbered—that is, not covered by any patents—alternative to the proprietary DEFLATE compression algorithm, which is often used in software applications for data compression.The library provides functions to compress and decompress data using the DEFLATE algorithm, which is a combination of the LZ77 algorithm and Huffman coding. zlib is notable for its versatility; it can be used in a wide range of applications, from web servers and web clients compressing HTTP data, to the compression of data for storage or transmission in various file formats, such as PNG, ZIP, and GZIP.")
txtLen := c.Ulong(len(txt))
cmpSize := zlib.CompressBound(txtLen)
cmpData := make([]byte, int(cmpSize))
res := zlib.Compress(unsafe.SliceData(cmpData), &cmpSize, unsafe.SliceData(txt), txtLen)
if res != zlib.OK {
c.Printf(c.Str("\nCompression failed: %d\n"), res)
return
}
c.Printf(c.Str("Text length = %d, Compressed size = %d\n"), txtLen, cmpSize)
ucmpSize := txtLen
ucmpData := make([]byte, int(ucmpSize))
unRes := zlib.Uncompress(unsafe.SliceData(ucmpData), &ucmpSize, unsafe.SliceData(cmpData), cmpSize)
c.Printf(c.Str("Decompression result = %d, Decompressed size %d\n"), unRes, ucmpSize)
if unRes != zlib.OK {
c.Printf(c.Str("\nDecompression failed: %d\n"), unRes)
return
}
c.Printf(c.Str("Decompressed data: \n"))
for i := 0; i < int(ucmpSize); i++ {
c.Printf(c.Str("%c"), ucmpData[i])
}
}
/* Expected output:
origin textLen = 73 compressed_size = 36
uncompress result = 0 uncompress result size 73
after uncompressed data: Hello, zlib compression!Hello, zlib compression!Hello, zlib compression!
*/

BIN
c/zlib/llgo_autogen.lla Normal file

Binary file not shown.

92
c/zlib/zlib.go Normal file
View File

@@ -0,0 +1,92 @@
/*
* Copyright (c) 2024 The GoPlus Authors (goplus.org). All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package zlib
import (
_ "unsafe"
"github.com/goplus/llgo/c"
)
const (
LLGoPackage = "link: $(pkg-config --libs zlib); -lz"
)
/* errno */
const (
OK = 0
STREAM_END = 1
NEED_DICT = 2
ERRNO = -1
STREAM_ERROR = -2
DATA_ERROR = -3
MEM_ERROR = -4
BUF_ERROR = -5
VERSION_ERROR = -6
)
/* compression levels */
const (
NO_COMPRESSION = 0
BEST_SPEED = 1
BEST_COMPRESSION = 9
DEFAULT_COMPRESSION = -1
)
const (
NO_FLUSH = 0
PARTIAL_FLUSH = 1
SYNC_FLUSH = 2
FULL_FLUSH = 3
FINISH = 4
BLOCK = 5
TREES = 6
)
const (
FILTERED = 1
HUFFMAN_ONLY = 2
RLE = 3
FIXED = 4
DEFAULT_STRATEGY = 0
)
const (
BINARY = 0
TEXT = 1
ASCII = TEXT
UNKNOWN = 2
)
const (
DEFLATED = 8
)
//go:linkname CompressBound C.compressBound
func CompressBound(sourceLen c.Ulong) c.Ulong
//go:linkname Compress C.compress
func Compress(dest *byte, destLen *c.Ulong, source *byte, sourceLen c.Ulong) c.Int
//go:linkname Compress2 C.compress2
func Compress2(dest *byte, destLen *c.Ulong, source *byte, sourceLen c.Ulong, level c.Int) c.Int
//go:linkname Uncompress C.uncompress
func Uncompress(dest *byte, destLen *c.Ulong, source *byte, sourceLen c.Ulong) c.Int
//go:linkname Uncompress2 C.uncompress2
func Uncompress2(dest *byte, destLen *c.Ulong, source *byte, sourceLen *c.Ulong) c.Int

View File

@@ -0,0 +1,63 @@
#include <clang-c/Index.h>
#include <iostream>
#include <string>
CXChildVisitResult visit(CXCursor c, CXCursor parent, CXClientData client_data);
void printAST(CXCursor cursor, unsigned int depth = 0) {
CXString cursorKind = clang_getCursorKindSpelling(clang_getCursorKind(cursor));
CXString cursorSpelling = clang_getCursorSpelling(cursor);
for (unsigned int i = 0; i < depth; ++i) {
std::cout << " ";
}
std::cout << clang_getCString(cursorKind) << ": "
<< clang_getCString(cursorSpelling) << std::endl;
clang_disposeString(cursorKind);
clang_disposeString(cursorSpelling);
CXCursor child;
clang_visitChildren(
cursor,
visit,
&depth
);
}
CXChildVisitResult visit(CXCursor c, CXCursor parent, CXClientData client_data) {
unsigned int* depth = (unsigned int*)client_data;
printAST(c, *depth + 1);
return CXChildVisit_Continue;
}
int main(int argc, char* argv[]) {
if (argc < 2) {
std::cerr << "Usage: " << argv[0] << " <header_file>" << std::endl;
return 1;
}
CXIndex index = clang_createIndex(0, 0);
CXTranslationUnit unit = clang_parseTranslationUnit(
index,
argv[1],
nullptr, 0,
nullptr, 0,
CXTranslationUnit_None
);
if (unit == nullptr) {
std::cerr << "Unable to parse translation unit. Quitting." << std::endl;
return 1;
}
CXCursor cursor = clang_getTranslationUnitCursor(unit);
std::cout << "AST for " << argv[1] << ":" << std::endl;
printAST(cursor);
clang_disposeTranslationUnit(unit);
clang_disposeIndex(index);
return 0;
}

2
chore/_xtool/astdump/build.sh Executable file
View File

@@ -0,0 +1,2 @@
export LLVM_DIR=/opt/homebrew/Cellar/llvm@17/17.0.6
clang -L$LLVM_DIR/lib -lclang -lc++ -I$LLVM_DIR/include astdump.cpp

View File

@@ -34,6 +34,7 @@ func main() {
llgen.Verbose = false
llgenDir(dir + "/cl/_testlibc")
llgenDir(dir + "/cl/_testlibgo")
llgenDir(dir + "/cl/_testrt")
llgenDir(dir + "/cl/_testgo")
llgenDir(dir+"/cl/_testpy", "")

View File

@@ -30,7 +30,7 @@ func main() {
return
}
nm := llvm.New().Nm()
nm := llvm.New("").Nm()
items, err := nm.List(os.Args[1])
for _, item := range items {
if item.File != "" {

View File

@@ -54,7 +54,7 @@ The commands are:
}
func makeIndex() {
env := llvm.New()
env := llvm.New("")
idxDir := indexDir()
os.MkdirAll(idxDir, 0755)

View File

@@ -1,7 +1,7 @@
; ModuleID = 'apkg'
source_filename = "apkg"
@"apkg.init$guard" = global ptr null
@"apkg.init$guard" = global i1 false, align 1
define double @apkg.Max(double %0, double %1) {
_llgo_0:

View File

@@ -1,9 +1,9 @@
; ModuleID = 'main'
source_filename = "main"
@"main.init$guard" = global ptr null
@__llgo_argc = global ptr null
@__llgo_argv = global ptr null
@"main.init$guard" = global i1 false, align 1
@__llgo_argc = global i32 0, align 4
@__llgo_argv = global ptr null, align 8
define void @main.init() {
_llgo_0:

View File

@@ -1,10 +1,10 @@
; ModuleID = 'main'
source_filename = "main"
@main.hello = global [7 x i8] undef
@"main.init$guard" = global ptr null
@__llgo_argc = global ptr null
@__llgo_argv = global ptr null
@main.hello = global [7 x i8] zeroinitializer, align 1
@"main.init$guard" = global i1 false, align 1
@__llgo_argc = global i32 0, align 4
@__llgo_argv = global ptr null, align 8
define void @main.init() {
_llgo_0:

Some files were not shown because too many files have changed in this diff Show More