From 556399bad6eb2c7e414b4eeef5f209e60582079b Mon Sep 17 00:00:00 2001 From: peefy Date: Mon, 25 Mar 2024 11:33:28 +0800 Subject: [PATCH] feat: add file.exsits and file.abs functions Signed-off-by: peefy --- kclvm/api/src/service/service_impl.rs | 6 +- .../kclvm_loader__tests__assign_stmt_0.snap | 2 +- .../kclvm_loader__tests__assign_stmt_1.snap | 2 +- .../kclvm_loader__tests__assign_stmt_2.snap | 2 +- .../kclvm_loader__tests__builtin_call_0.snap | 28 ++-- .../kclvm_loader__tests__builtin_call_1.snap | 90 ++++++------- .../kclvm_loader__tests__builtin_call_2.snap | 94 ++++++------- .../kclvm_loader__tests__import_stmt_0.snap | 2 +- .../kclvm_loader__tests__import_stmt_1.snap | 2 +- kclvm/runtime/src/_kclvm.bc | Bin 14020 -> 14084 bytes kclvm/runtime/src/_kclvm.h | 8 +- kclvm/runtime/src/_kclvm.ll | 8 +- kclvm/runtime/src/_kclvm.rs | 2 + kclvm/runtime/src/_kclvm_addr.rs | 2 + kclvm/runtime/src/_kclvm_api_spec.rs | 16 ++- kclvm/runtime/src/file/mod.rs | 60 ++++++++- kclvm/runtime/src/value/val_args.rs | 17 +++ kclvm/sema/src/builtin/system_module.rs | 124 +++++++++--------- test/grammar/builtins/file/exists/a.k | 1 + test/grammar/builtins/file/exists/main.k | 4 + .../builtins/file/exists/stdout.golden | 2 + 21 files changed, 281 insertions(+), 191 deletions(-) create mode 100644 test/grammar/builtins/file/exists/a.k create mode 100644 test/grammar/builtins/file/exists/main.k create mode 100644 test/grammar/builtins/file/exists/stdout.golden diff --git a/kclvm/api/src/service/service_impl.rs b/kclvm/api/src/service/service_impl.rs index 7e46eae4f..27463aa07 100644 --- a/kclvm/api/src/service/service_impl.rs +++ b/kclvm/api/src/service/service_impl.rs @@ -173,9 +173,9 @@ impl KclvmServiceImpl { /// assert_eq!(result.type_errors.len(), 0); /// assert_eq!(result.symbols.len(), 12); /// assert_eq!(result.scopes.len(), 3); - /// assert_eq!(result.node_symbol_map.len(), 165); - /// assert_eq!(result.symbol_node_map.len(), 165); - /// assert_eq!(result.fully_qualified_name_map.len(), 173); + /// assert_eq!(result.node_symbol_map.len(), 167); + /// assert_eq!(result.symbol_node_map.len(), 167); + /// assert_eq!(result.fully_qualified_name_map.len(), 175); /// assert_eq!(result.pkg_scope_map.len(), 3); /// ``` pub fn load_package(&self, args: &LoadPackageArgs) -> anyhow::Result { diff --git a/kclvm/loader/src/snapshots/kclvm_loader__tests__assign_stmt_0.snap b/kclvm/loader/src/snapshots/kclvm_loader__tests__assign_stmt_0.snap index 9d2df302e..a31f3672f 100644 --- a/kclvm/loader/src/snapshots/kclvm_loader__tests__assign_stmt_0.snap +++ b/kclvm/loader/src/snapshots/kclvm_loader__tests__assign_stmt_0.snap @@ -38,7 +38,7 @@ expression: "format!(\"{:#?}\", p.symbols.values())" def: Some( SymbolRef { id: Index { - index: 153, + index: 155, generation: 0, }, kind: Value, diff --git a/kclvm/loader/src/snapshots/kclvm_loader__tests__assign_stmt_1.snap b/kclvm/loader/src/snapshots/kclvm_loader__tests__assign_stmt_1.snap index bea187443..6a653e36d 100644 --- a/kclvm/loader/src/snapshots/kclvm_loader__tests__assign_stmt_1.snap +++ b/kclvm/loader/src/snapshots/kclvm_loader__tests__assign_stmt_1.snap @@ -38,7 +38,7 @@ expression: "format!(\"{:#?}\", p.symbols.values())" def: Some( SymbolRef { id: Index { - index: 153, + index: 155, generation: 0, }, kind: Value, diff --git a/kclvm/loader/src/snapshots/kclvm_loader__tests__assign_stmt_2.snap b/kclvm/loader/src/snapshots/kclvm_loader__tests__assign_stmt_2.snap index e8a5af937..08aa0aaa5 100644 --- a/kclvm/loader/src/snapshots/kclvm_loader__tests__assign_stmt_2.snap +++ b/kclvm/loader/src/snapshots/kclvm_loader__tests__assign_stmt_2.snap @@ -38,7 +38,7 @@ expression: "format!(\"{:#?}\", p.symbols.values())" def: Some( SymbolRef { id: Index { - index: 153, + index: 155, generation: 0, }, kind: Value, diff --git a/kclvm/loader/src/snapshots/kclvm_loader__tests__builtin_call_0.snap b/kclvm/loader/src/snapshots/kclvm_loader__tests__builtin_call_0.snap index 2fa92773c..c3d458a6d 100644 --- a/kclvm/loader/src/snapshots/kclvm_loader__tests__builtin_call_0.snap +++ b/kclvm/loader/src/snapshots/kclvm_loader__tests__builtin_call_0.snap @@ -88,20 +88,6 @@ expression: "format!(\"{:#?}\", p.symbols.values())" }, ), attrs: [ - SymbolRef { - id: Index { - index: 124, - generation: 0, - }, - kind: Value, - }, - SymbolRef { - id: Index { - index: 125, - generation: 0, - }, - kind: Value, - }, SymbolRef { id: Index { index: 126, @@ -291,6 +277,20 @@ expression: "format!(\"{:#?}\", p.symbols.values())" }, kind: Value, }, + SymbolRef { + id: Index { + index: 153, + generation: 0, + }, + kind: Value, + }, + SymbolRef { + id: Index { + index: 154, + generation: 0, + }, + kind: Value, + }, ], is_global: false, }, diff --git a/kclvm/loader/src/snapshots/kclvm_loader__tests__builtin_call_1.snap b/kclvm/loader/src/snapshots/kclvm_loader__tests__builtin_call_1.snap index 9992e7e81..6db2e0ce0 100644 --- a/kclvm/loader/src/snapshots/kclvm_loader__tests__builtin_call_1.snap +++ b/kclvm/loader/src/snapshots/kclvm_loader__tests__builtin_call_1.snap @@ -38,7 +38,7 @@ expression: "format!(\"{:#?}\", p.symbols.values())" def: Some( SymbolRef { id: Index { - index: 153, + index: 155, generation: 0, }, kind: Value, @@ -180,20 +180,6 @@ expression: "format!(\"{:#?}\", p.symbols.values())" }, ), attrs: [ - SymbolRef { - id: Index { - index: 124, - generation: 0, - }, - kind: Value, - }, - SymbolRef { - id: Index { - index: 125, - generation: 0, - }, - kind: Value, - }, SymbolRef { id: Index { index: 126, @@ -383,6 +369,20 @@ expression: "format!(\"{:#?}\", p.symbols.values())" }, kind: Value, }, + SymbolRef { + id: Index { + index: 153, + generation: 0, + }, + kind: Value, + }, + SymbolRef { + id: Index { + index: 154, + generation: 0, + }, + kind: Value, + }, ], is_global: false, }, @@ -415,27 +415,13 @@ expression: "format!(\"{:#?}\", p.symbols.values())" def: Some( SymbolRef { id: Index { - index: 154, + index: 156, generation: 0, }, kind: Value, }, ), attrs: [ - SymbolRef { - id: Index { - index: 124, - generation: 0, - }, - kind: Value, - }, - SymbolRef { - id: Index { - index: 125, - generation: 0, - }, - kind: Value, - }, SymbolRef { id: Index { index: 126, @@ -625,6 +611,20 @@ expression: "format!(\"{:#?}\", p.symbols.values())" }, kind: Value, }, + SymbolRef { + id: Index { + index: 153, + generation: 0, + }, + kind: Value, + }, + SymbolRef { + id: Index { + index: 154, + generation: 0, + }, + kind: Value, + }, ], is_global: false, }, @@ -664,20 +664,6 @@ expression: "format!(\"{:#?}\", p.symbols.values())" }, ), attrs: [ - SymbolRef { - id: Index { - index: 124, - generation: 0, - }, - kind: Value, - }, - SymbolRef { - id: Index { - index: 125, - generation: 0, - }, - kind: Value, - }, SymbolRef { id: Index { index: 126, @@ -867,6 +853,20 @@ expression: "format!(\"{:#?}\", p.symbols.values())" }, kind: Value, }, + SymbolRef { + id: Index { + index: 153, + generation: 0, + }, + kind: Value, + }, + SymbolRef { + id: Index { + index: 154, + generation: 0, + }, + kind: Value, + }, ], is_global: false, }, @@ -899,7 +899,7 @@ expression: "format!(\"{:#?}\", p.symbols.values())" def: Some( SymbolRef { id: Index { - index: 155, + index: 157, generation: 0, }, kind: Value, diff --git a/kclvm/loader/src/snapshots/kclvm_loader__tests__builtin_call_2.snap b/kclvm/loader/src/snapshots/kclvm_loader__tests__builtin_call_2.snap index bc25f9377..0e68fc676 100644 --- a/kclvm/loader/src/snapshots/kclvm_loader__tests__builtin_call_2.snap +++ b/kclvm/loader/src/snapshots/kclvm_loader__tests__builtin_call_2.snap @@ -99,7 +99,7 @@ expression: "format!(\"{:#?}\", p.symbols.values())" def: Some( SymbolRef { id: Index { - index: 153, + index: 155, generation: 0, }, kind: Value, @@ -240,7 +240,7 @@ expression: "format!(\"{:#?}\", p.symbols.values())" def: Some( SymbolRef { id: Index { - index: 154, + index: 156, generation: 0, }, kind: Value, @@ -337,7 +337,7 @@ expression: "format!(\"{:#?}\", p.symbols.values())" def: Some( SymbolRef { id: Index { - index: 153, + index: 155, generation: 0, }, kind: Value, @@ -382,20 +382,6 @@ expression: "format!(\"{:#?}\", p.symbols.values())" }, ), attrs: [ - SymbolRef { - id: Index { - index: 124, - generation: 0, - }, - kind: Value, - }, - SymbolRef { - id: Index { - index: 125, - generation: 0, - }, - kind: Value, - }, SymbolRef { id: Index { index: 126, @@ -585,6 +571,20 @@ expression: "format!(\"{:#?}\", p.symbols.values())" }, kind: Value, }, + SymbolRef { + id: Index { + index: 153, + generation: 0, + }, + kind: Value, + }, + SymbolRef { + id: Index { + index: 154, + generation: 0, + }, + kind: Value, + }, ], is_global: false, }, @@ -617,27 +617,13 @@ expression: "format!(\"{:#?}\", p.symbols.values())" def: Some( SymbolRef { id: Index { - index: 155, + index: 157, generation: 0, }, kind: Value, }, ), attrs: [ - SymbolRef { - id: Index { - index: 124, - generation: 0, - }, - kind: Value, - }, - SymbolRef { - id: Index { - index: 125, - generation: 0, - }, - kind: Value, - }, SymbolRef { id: Index { index: 126, @@ -827,6 +813,20 @@ expression: "format!(\"{:#?}\", p.symbols.values())" }, kind: Value, }, + SymbolRef { + id: Index { + index: 153, + generation: 0, + }, + kind: Value, + }, + SymbolRef { + id: Index { + index: 154, + generation: 0, + }, + kind: Value, + }, ], is_global: false, }, @@ -866,20 +866,6 @@ expression: "format!(\"{:#?}\", p.symbols.values())" }, ), attrs: [ - SymbolRef { - id: Index { - index: 124, - generation: 0, - }, - kind: Value, - }, - SymbolRef { - id: Index { - index: 125, - generation: 0, - }, - kind: Value, - }, SymbolRef { id: Index { index: 126, @@ -1069,6 +1055,20 @@ expression: "format!(\"{:#?}\", p.symbols.values())" }, kind: Value, }, + SymbolRef { + id: Index { + index: 153, + generation: 0, + }, + kind: Value, + }, + SymbolRef { + id: Index { + index: 154, + generation: 0, + }, + kind: Value, + }, ], is_global: false, }, @@ -1101,7 +1101,7 @@ expression: "format!(\"{:#?}\", p.symbols.values())" def: Some( SymbolRef { id: Index { - index: 156, + index: 158, generation: 0, }, kind: Value, diff --git a/kclvm/loader/src/snapshots/kclvm_loader__tests__import_stmt_0.snap b/kclvm/loader/src/snapshots/kclvm_loader__tests__import_stmt_0.snap index a77fff589..7e5f680ef 100644 --- a/kclvm/loader/src/snapshots/kclvm_loader__tests__import_stmt_0.snap +++ b/kclvm/loader/src/snapshots/kclvm_loader__tests__import_stmt_0.snap @@ -195,7 +195,7 @@ expression: "format!(\"{:#?}\", p.symbols.values())" def: Some( SymbolRef { id: Index { - index: 153, + index: 155, generation: 0, }, kind: Value, diff --git a/kclvm/loader/src/snapshots/kclvm_loader__tests__import_stmt_1.snap b/kclvm/loader/src/snapshots/kclvm_loader__tests__import_stmt_1.snap index 9f068a42a..25404f899 100644 --- a/kclvm/loader/src/snapshots/kclvm_loader__tests__import_stmt_1.snap +++ b/kclvm/loader/src/snapshots/kclvm_loader__tests__import_stmt_1.snap @@ -38,7 +38,7 @@ expression: "format!(\"{:#?}\", p.symbols.values())" def: Some( SymbolRef { id: Index { - index: 153, + index: 155, generation: 0, }, kind: Value, diff --git a/kclvm/runtime/src/_kclvm.bc b/kclvm/runtime/src/_kclvm.bc index 4827eba6a00a203b17f50e8bac199147969efe5e..36de587944fe2a01d5c174e84f475ca55fcd7100 100644 GIT binary patch delta 3940 zcmZXXdrVVj7{<>jH!D~WQa}`Kk&7z@aiT#)t=MjW4nZ*rq7-ja1UCV-^TIg@U6IBF zoK<7gX}yeA88D)5nTnt;lWmzyySQZ6hF}?Q z$v1paXUp%=D&A5+(y4)>xmhf4DO{T&y|z1Mq$iA_C=!>tnhx=i@dC+qLv1;YA~UZRoc7WQ<}xOB7M>;ZxCm47;a~ zqutw)XtLXq4*zT=gq1whD?(v6pFh)?U;I?OBZwFEJ38A0>0a)=MS~XwMaLgg;6>l$ zoOVoiAk3UUoUW74B$i|+IQh8z$wShu_cc6&INMmsLM+cY6yA3Y6;>$yCZWQGk{lqj-V&0v%n*=ORj_2K3%^Sh5(&W=9G%JDcikX_x*K*VC0->iB3JS@Y9g6fNrq`6vv#`Ap@D z7L;xaszImzo~eZ}#-i1IiQAoi-ioJ2J*4M@Q#Zbu0GiV(DHQf2I&hQo1qlZX&o)f64F~p1La#T~J6T2!_(k*~|hE#PZWl!DOu- z2tqyT`-|;3F&hW34&hKzRXy&)p)_kwQ)h}R2dDp}{p^4EogD`X+Xib)kZZ}mh6Jxy zr;W)!`0fk{>kbgdN5XD547E0iit;>U*z998qV0Y%&l*>BdnP`=?gi84L8I$Y~3q*cPB)Gngsj=v?W{Yt=nCgPD=&WO6 z1Z1nT)C{6M-tR_pibBX56*Q8Wmk7u-AA45@s+|AicoTWeOU*x`x~G+Nzeimzf71Hp z2kHh;-jez1|4`n`F-;B75w@qn_cOqL>#jW?MY9eH=Zg&18y((vkZ)Bnlb$M;@d8P@ zFOx=}_6Ga!A7TZ3%z}&|qfv@D4xM>2*9qaO+yIZGyr?w$r*9Osc zou%7AF=-R4xcHnkfpvhsUfIKebm^t_=?@+ZSTi}8;KG-*IsK9E_H6Rk*ARk#MpHhm@_J6|D3vVlh; zPBXXu6xV@UZtHQlDw_QTck9ZqMM(C2qSH=JF!FGkb*#`!bIvSZ(O?x^mEBDdsR5%j{7osFC%p8UynhXEu)L8J2>Ik-dUIgux92+nDhy7;c2sh1U8HpwVuSNZqVw#UaE2>c(z C_+UE# delta 3862 zcmZWseNdBi9Dla)(wGe!w+&yGqXUr#P)a=!0jFZ&d}V-6L)=Ku9hV%Ylv4TZ)TKhyR1$SJgesDp(@n?myfZC({Ym z$hNZg4%;KOf;AG&_TA7YBJg5)Y2}~D*2Im=T#IzisK;ahUFQQ?M;g%e_Sq~dtKeLo z?z4@Bh|kTLr@*$zO&50gqxtzW#M++d=wz_Ac!YcbTAMra7+TwysY7eeudc-OJa;bx z1y)=Uae9E3v`exZi0acQWXci>8GCJHEh1}}Ocl+Zew=}NuwO)Ddnne&wx^?^N4KP?{m}ya zN$Pg~A~}tz%RVw=e%NkOE|j0!f~P9E*h17pJ&J0q=3Fih1gZb^gFV&QGLPg|wm_A- zD@UEJ#42rxEzgicCQX0(0~@Vn!VeMn$$%*!aDYF_IM;yrsx`ceZ(hC6B=2IltZC=< z7_L`qJ|%%}^P9ukg*3j*&wdOvICgR3q4mI{I8!k{2Rw^;SxSkVuP8u~_ast9Xr4uD z{HZmNa{>NDlbX>lVbblJD@OY#9?HX{v**&tYG`D`lPF{>^g0gh@7W!M=J$dibF!ja zC~vv*SRcyUqt^|9yzGZbt_`4Wr&rNFHK?wSKk2^ql~Ohl?2kONd6GishvEAqS@O=( zyD3twV2v-=v7%nYcjI%%JTZ*c=d<%tM8UyNLXf%7a`B^U5uh?Y&JY5~A4Tx#KdD)n zWaWPZ9+I9)Z)*qQbFC2fV0!KxUqIpeXRo!C#~1LQ@!fM$=4PTD75n}!LmpLgO}K5z z{yW&jj!Y_u!fho7F2gp?aBy-0wa;*n3g?_s(2f)R--C`0oakxui&8;kcSG{&y^sXT z+i}J@Bnd+Nd6DgXQXIj~{k0WNZECq&>)2K2ahqGzNeZwip zpTFk17hBM<%S{i!FoVsq6Z^#Vb{7t(s-w2g02#YbmI}x^n>kepKy&X*_d^S?=aEf* z(}>8rPB$PjXN4J&-MDogHB+|C6d)t~`RcN5V-Z@cdNCklv&T}%PL$*$GEcJyk#(<0 zKxBqLrt`>x`ukjO``L!g)%!JNr_!R1ADl$Q^)s^VauP1|kQ|D<-PVRz@2tmVR|mB( zj_>^IyB|fs_|l!*T8(wzSZd0_Bwss@s)eVe%TW@`_m>}Fp{`oCU8G^S!S6RQeKZf- zvzf0WkC E50SV@5&!@I diff --git a/kclvm/runtime/src/_kclvm.h b/kclvm/runtime/src/_kclvm.h index dac0ba05f..8d4735af8 100644 --- a/kclvm/runtime/src/_kclvm.h +++ b/kclvm/runtime/src/_kclvm.h @@ -304,11 +304,15 @@ void kclvm_dict_update_key_value(kclvm_value_ref_t* p, kclvm_value_ref_t* key, k kclvm_value_ref_t* kclvm_dict_values(kclvm_context_t* ctx, kclvm_value_ref_t* p); -kclvm_value_ref_t* kclvm_file_glob(kclvm_context_t* ctx, kclvm_value_ref_t* args, kclvm_value_ref_t* _kwargs); +kclvm_value_ref_t* kclvm_file_abs(kclvm_context_t* ctx, kclvm_value_ref_t* args, kclvm_value_ref_t* kwargs); + +kclvm_value_ref_t* kclvm_file_exists(kclvm_context_t* ctx, kclvm_value_ref_t* args, kclvm_value_ref_t* kwargs); + +kclvm_value_ref_t* kclvm_file_glob(kclvm_context_t* ctx, kclvm_value_ref_t* args, kclvm_value_ref_t* kwargs); kclvm_value_ref_t* kclvm_file_modpath(kclvm_context_t* ctx, kclvm_value_ref_t* _args, kclvm_value_ref_t* _kwargs); -kclvm_value_ref_t* kclvm_file_read(kclvm_context_t* ctx, kclvm_value_ref_t* args, kclvm_value_ref_t* _kwargs); +kclvm_value_ref_t* kclvm_file_read(kclvm_context_t* ctx, kclvm_value_ref_t* args, kclvm_value_ref_t* kwargs); kclvm_value_ref_t* kclvm_file_workdir(kclvm_context_t* ctx, kclvm_value_ref_t* _args, kclvm_value_ref_t* _kwargs); diff --git a/kclvm/runtime/src/_kclvm.ll b/kclvm/runtime/src/_kclvm.ll index 20bf1d8d3..c5e884966 100644 --- a/kclvm/runtime/src/_kclvm.ll +++ b/kclvm/runtime/src/_kclvm.ll @@ -252,11 +252,15 @@ declare void @kclvm_dict_update_key_value(%kclvm_value_ref_t* %p, %kclvm_value_r declare %kclvm_value_ref_t* @kclvm_dict_values(%kclvm_context_t* %ctx, %kclvm_value_ref_t* %p); -declare %kclvm_value_ref_t* @kclvm_file_glob(%kclvm_context_t* %ctx, %kclvm_value_ref_t* %args, %kclvm_value_ref_t* %_kwargs); +declare %kclvm_value_ref_t* @kclvm_file_abs(%kclvm_context_t* %ctx, %kclvm_value_ref_t* %args, %kclvm_value_ref_t* %kwargs); + +declare %kclvm_value_ref_t* @kclvm_file_exists(%kclvm_context_t* %ctx, %kclvm_value_ref_t* %args, %kclvm_value_ref_t* %kwargs); + +declare %kclvm_value_ref_t* @kclvm_file_glob(%kclvm_context_t* %ctx, %kclvm_value_ref_t* %args, %kclvm_value_ref_t* %kwargs); declare %kclvm_value_ref_t* @kclvm_file_modpath(%kclvm_context_t* %ctx, %kclvm_value_ref_t* %_args, %kclvm_value_ref_t* %_kwargs); -declare %kclvm_value_ref_t* @kclvm_file_read(%kclvm_context_t* %ctx, %kclvm_value_ref_t* %args, %kclvm_value_ref_t* %_kwargs); +declare %kclvm_value_ref_t* @kclvm_file_read(%kclvm_context_t* %ctx, %kclvm_value_ref_t* %args, %kclvm_value_ref_t* %kwargs); declare %kclvm_value_ref_t* @kclvm_file_workdir(%kclvm_context_t* %ctx, %kclvm_value_ref_t* %_args, %kclvm_value_ref_t* %_kwargs); diff --git a/kclvm/runtime/src/_kclvm.rs b/kclvm/runtime/src/_kclvm.rs index 72768d395..14e5ee6a8 100644 --- a/kclvm/runtime/src/_kclvm.rs +++ b/kclvm/runtime/src/_kclvm.rs @@ -137,6 +137,8 @@ pub enum ApiFunc { kclvm_dict_update, kclvm_dict_update_key_value, kclvm_dict_values, + kclvm_file_abs, + kclvm_file_exists, kclvm_file_glob, kclvm_file_modpath, kclvm_file_read, diff --git a/kclvm/runtime/src/_kclvm_addr.rs b/kclvm/runtime/src/_kclvm_addr.rs index c2e3517b9..5c745c043 100644 --- a/kclvm/runtime/src/_kclvm_addr.rs +++ b/kclvm/runtime/src/_kclvm_addr.rs @@ -142,6 +142,8 @@ pub fn _kclvm_get_fn_ptr_by_name(name: &str) -> u64 { "kclvm_dict_update" => crate::kclvm_dict_update as *const () as u64, "kclvm_dict_update_key_value" => crate::kclvm_dict_update_key_value as *const () as u64, "kclvm_dict_values" => crate::kclvm_dict_values as *const () as u64, + "kclvm_file_abs" => crate::kclvm_file_abs as *const () as u64, + "kclvm_file_exists" => crate::kclvm_file_exists as *const () as u64, "kclvm_file_glob" => crate::kclvm_file_glob as *const () as u64, "kclvm_file_modpath" => crate::kclvm_file_modpath as *const () as u64, "kclvm_file_read" => crate::kclvm_file_read as *const () as u64, diff --git a/kclvm/runtime/src/_kclvm_api_spec.rs b/kclvm/runtime/src/_kclvm_api_spec.rs index 9ad370a5d..ebc6cbadb 100644 --- a/kclvm/runtime/src/_kclvm_api_spec.rs +++ b/kclvm/runtime/src/_kclvm_api_spec.rs @@ -1199,12 +1199,12 @@ // api-spec(llvm): declare %kclvm_value_ref_t* @kclvm_yaml_validate(%kclvm_context_t* %ctx, %kclvm_value_ref_t* %args, %kclvm_value_ref_t* %_kwargs); // api-spec: kclvm_file_read -// api-spec(c): kclvm_value_ref_t* kclvm_file_read(kclvm_context_t* ctx, kclvm_value_ref_t* args, kclvm_value_ref_t* _kwargs); -// api-spec(llvm): declare %kclvm_value_ref_t* @kclvm_file_read(%kclvm_context_t* %ctx, %kclvm_value_ref_t* %args, %kclvm_value_ref_t* %_kwargs); +// api-spec(c): kclvm_value_ref_t* kclvm_file_read(kclvm_context_t* ctx, kclvm_value_ref_t* args, kclvm_value_ref_t* kwargs); +// api-spec(llvm): declare %kclvm_value_ref_t* @kclvm_file_read(%kclvm_context_t* %ctx, %kclvm_value_ref_t* %args, %kclvm_value_ref_t* %kwargs); // api-spec: kclvm_file_glob -// api-spec(c): kclvm_value_ref_t* kclvm_file_glob(kclvm_context_t* ctx, kclvm_value_ref_t* args, kclvm_value_ref_t* _kwargs); -// api-spec(llvm): declare %kclvm_value_ref_t* @kclvm_file_glob(%kclvm_context_t* %ctx, %kclvm_value_ref_t* %args, %kclvm_value_ref_t* %_kwargs); +// api-spec(c): kclvm_value_ref_t* kclvm_file_glob(kclvm_context_t* ctx, kclvm_value_ref_t* args, kclvm_value_ref_t* kwargs); +// api-spec(llvm): declare %kclvm_value_ref_t* @kclvm_file_glob(%kclvm_context_t* %ctx, %kclvm_value_ref_t* %args, %kclvm_value_ref_t* %kwargs); // api-spec: kclvm_file_modpath // api-spec(c): kclvm_value_ref_t* kclvm_file_modpath(kclvm_context_t* ctx, kclvm_value_ref_t* _args, kclvm_value_ref_t* _kwargs); @@ -1214,3 +1214,11 @@ // api-spec(c): kclvm_value_ref_t* kclvm_file_workdir(kclvm_context_t* ctx, kclvm_value_ref_t* _args, kclvm_value_ref_t* _kwargs); // api-spec(llvm): declare %kclvm_value_ref_t* @kclvm_file_workdir(%kclvm_context_t* %ctx, %kclvm_value_ref_t* %_args, %kclvm_value_ref_t* %_kwargs); +// api-spec: kclvm_file_exists +// api-spec(c): kclvm_value_ref_t* kclvm_file_exists(kclvm_context_t* ctx, kclvm_value_ref_t* args, kclvm_value_ref_t* kwargs); +// api-spec(llvm): declare %kclvm_value_ref_t* @kclvm_file_exists(%kclvm_context_t* %ctx, %kclvm_value_ref_t* %args, %kclvm_value_ref_t* %kwargs); + +// api-spec: kclvm_file_abs +// api-spec(c): kclvm_value_ref_t* kclvm_file_abs(kclvm_context_t* ctx, kclvm_value_ref_t* args, kclvm_value_ref_t* kwargs); +// api-spec(llvm): declare %kclvm_value_ref_t* @kclvm_file_abs(%kclvm_context_t* %ctx, %kclvm_value_ref_t* %args, %kclvm_value_ref_t* %kwargs); + diff --git a/kclvm/runtime/src/file/mod.rs b/kclvm/runtime/src/file/mod.rs index c4dae91fc..1536f40a1 100644 --- a/kclvm/runtime/src/file/mod.rs +++ b/kclvm/runtime/src/file/mod.rs @@ -2,18 +2,20 @@ use std::fs; use crate::*; use glob::glob; +use std::path::Path; #[no_mangle] #[runtime_fn] pub extern "C" fn kclvm_file_read( ctx: *mut kclvm_context_t, args: *const kclvm_value_ref_t, - _kwargs: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, ) -> *const kclvm_value_ref_t { let args = ptr_as_ref(args); + let kwargs = ptr_as_ref(kwargs); let ctx = mut_ptr_as_ref(ctx); - if let Some(x) = args.arg_i_str(0, None) { + if let Some(x) = get_call_args_str(&args, &kwargs, 0, Some("filepath")) { let contents = fs::read_to_string(&x) .unwrap_or_else(|e| panic!("failed to access the file '{}': {}", x, e)); @@ -29,13 +31,13 @@ pub extern "C" fn kclvm_file_read( pub extern "C" fn kclvm_file_glob( ctx: *mut kclvm_context_t, args: *const kclvm_value_ref_t, - _kwargs: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, ) -> *const kclvm_value_ref_t { let args = ptr_as_ref(args); + let kwargs = ptr_as_ref(kwargs); let ctx = mut_ptr_as_ref(ctx); - let pattern = args - .arg_i_str(0, None) + let pattern = get_call_args_str(&args, &kwargs, 0, Some("pattern")) .expect("glob() takes exactly one argument (0 given)"); let mut matched_paths = vec![]; @@ -46,7 +48,7 @@ pub extern "C" fn kclvm_file_glob( } } - return ValueRef::list_str(matched_paths.as_slice()).into_raw(ctx); + ValueRef::list_str(matched_paths.as_slice()).into_raw(ctx) } #[no_mangle] @@ -72,3 +74,49 @@ pub extern "C" fn kclvm_file_workdir( let s = ValueRef::str(ctx.workdir.as_ref()); s.into_raw(ctx) } + +/// Whether this file path exists. Returns true if the path points at +/// an existing entity. This function will traverse symbolic links to +/// query information about the destination file. +#[no_mangle] +#[runtime_fn] +pub extern "C" fn kclvm_file_exists( + ctx: *mut kclvm_context_t, + args: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, +) -> *const kclvm_value_ref_t { + let args = ptr_as_ref(args); + let kwargs = ptr_as_ref(kwargs); + let ctx = mut_ptr_as_ref(ctx); + + if let Some(path) = get_call_args_str(&args, &kwargs, 0, Some("filepath")) { + let exist = Path::new(&path).exists(); + return ValueRef::bool(exist).into_raw(ctx); + } + + panic!("read() takes exactly one argument (0 given)"); +} + +/// Returns the canonical, absolute form of the path with all intermediate +/// components normalized and symbolic links resolved. +#[no_mangle] +#[runtime_fn] +pub extern "C" fn kclvm_file_abs( + ctx: *mut kclvm_context_t, + args: *const kclvm_value_ref_t, + kwargs: *const kclvm_value_ref_t, +) -> *const kclvm_value_ref_t { + let args = ptr_as_ref(args); + let kwargs = ptr_as_ref(kwargs); + let ctx = mut_ptr_as_ref(ctx); + + if let Some(path) = get_call_args_str(&args, &kwargs, 0, Some("filepath")) { + if let Ok(abs_path) = Path::new(&path).canonicalize() { + return ValueRef::str(abs_path.to_str().unwrap()).into_raw(ctx); + } else { + panic!("Could not get the absolute path of {path}"); + } + } + + panic!("read() takes exactly one argument (0 given)"); +} diff --git a/kclvm/runtime/src/value/val_args.rs b/kclvm/runtime/src/value/val_args.rs index 2e9a83169..959350c59 100644 --- a/kclvm/runtime/src/value/val_args.rs +++ b/kclvm/runtime/src/value/val_args.rs @@ -215,6 +215,23 @@ impl ValueRef { } } +pub(crate) fn get_call_args_str( + args: &ValueRef, + kwargs: &ValueRef, + index: usize, + key: Option<&str>, +) -> Option { + if let Some(key) = key { + if let Some(val) = kwargs.get_by_key(key) { + return Some(val.as_str()); + } + } + if index < args.len() { + return Some(args.list_get(index as isize).unwrap().as_str()); + } + None +} + #[cfg(test)] mod test_value_args { use crate::*; diff --git a/kclvm/sema/src/builtin/system_module.rs b/kclvm/sema/src/builtin/system_module.rs index 12e4a1844..2504efd7f 100644 --- a/kclvm/sema/src/builtin/system_module.rs +++ b/kclvm/sema/src/builtin/system_module.rs @@ -11,7 +11,6 @@ use once_cell::sync::Lazy; // ------------------------------ pub const BASE64: &str = "base64"; -pub const BASE64_FUNCTION_NAMES: &[&str] = &["encode", "decode"]; macro_rules! register_base64_member { ($($name:ident => $ty:expr)*) => ( pub const BASE64_FUNCTION_TYPES: Lazy> = Lazy::new(|| { @@ -19,6 +18,9 @@ macro_rules! register_base64_member { $( builtin_mapping.insert(stringify!($name).to_string(), $ty); )* builtin_mapping }); + pub const BASE64_FUNCTION_NAMES: &[&str] = &[ + $( stringify!($name), )* + ]; ) } register_base64_member! { @@ -67,24 +69,6 @@ register_base64_member! { // ------------------------------ pub const NET: &str = "net"; -pub const NET_FUNCTION_NAMES: &[&str] = &[ - "split_host_port", - "join_host_port", - "fqdn", - "parse_IP", - "to_IP4", - "to_IP16", - "IP_string", - "is_IPv4", - "is_IP", - "is_loopback_IP", - "is_multicast_IP", - "is_interface_local_multicast_IP", - "is_link_local_multicast_IP", - "is_link_local_unicast_IP", - "is_global_unicast_IP", - "is_unspecified_IP", -]; macro_rules! register_net_member { ($($name:ident => $ty:expr)*) => ( pub const NET_FUNCTION_TYPES: Lazy> = Lazy::new(|| { @@ -92,6 +76,9 @@ macro_rules! register_net_member { $( builtin_mapping.insert(stringify!($name).to_string(), $ty); )* builtin_mapping }); + pub const NET_FUNCTION_NAMES: &[&str] = &[ + $( stringify!($name), )* + ]; ) } register_net_member! { @@ -331,7 +318,6 @@ register_net_member! { // ------------------------------ pub const MANIFESTS: &str = "manifests"; -pub const MANIFESTS_FUNCTION_NAMES: &[&str] = &["yaml_stream"]; macro_rules! register_manifests_member { ($($name:ident => $ty:expr)*) => ( pub const MANIFESTS_FUNCTION_TYPES: Lazy> = Lazy::new(|| { @@ -339,6 +325,9 @@ macro_rules! register_manifests_member { $( builtin_mapping.insert(stringify!($name).to_string(), $ty); )* builtin_mapping }); + pub const MANIFESTS_FUNCTION_NAMES: &[&str] = &[ + $( stringify!($name), )* + ]; ) } register_manifests_member! { @@ -375,24 +364,6 @@ opts - The YAML serialization options // ------------------------------ pub const MATH: &str = "math"; -pub const MATH_FUNCTION_NAMES: &[&str] = &[ - "ceil", - "factorial", - "floor", - "gcd", - "isfinite", - "isinf", - "isnan", - "modf", - "exp", - "expm1", - "log", - "log1p", - "log2", - "log10", - "pow", - "sqrt", -]; macro_rules! register_math_member { ($($name:ident => $ty:expr)*) => ( pub const MATH_FUNCTION_TYPES: Lazy> = Lazy::new(|| { @@ -400,6 +371,9 @@ macro_rules! register_math_member { $( builtin_mapping.insert(stringify!($name).to_string(), $ty); )* builtin_mapping }); + pub const MATH_FUNCTION_NAMES: &[&str] = &[ + $( stringify!($name), )* + ]; ) } register_math_member! { @@ -649,7 +623,6 @@ register_math_member! { // ------------------------------ pub const DATETIME: &str = "datetime"; -pub const DATETIME_FUNCTION_NAMES: [&str; 4] = ["today", "now", "ticks", "date"]; macro_rules! register_datetime_member { ($($name:ident => $ty:expr)*) => ( pub const DATETIME_FUNCTION_TYPES: Lazy> = Lazy::new(|| { @@ -657,6 +630,9 @@ macro_rules! register_datetime_member { $( builtin_mapping.insert(stringify!($name).to_string(), $ty); )* builtin_mapping }); + pub const DATETIME_FUNCTION_NAMES: &[&str] = &[ + $( stringify!($name), )* + ]; ) } register_datetime_member! { @@ -699,8 +675,6 @@ register_datetime_member! { // ------------------------------ pub const REGEX: &str = "regex"; -pub const REGEX_FUNCTION_NAMES: &[&str] = - &["replace", "match", "compile", "findall", "search", "split"]; macro_rules! register_regex_member { ($($name:ident => $ty:expr)*) => ( pub const REGEX_FUNCTION_TYPES: Lazy> = Lazy::new(|| { @@ -708,6 +682,9 @@ macro_rules! register_regex_member { $( builtin_mapping.insert(stringify!($name).to_string(), $ty); )* builtin_mapping }); + pub const REGEX_FUNCTION_NAMES: &[&str] = &[ + $( stringify!($name), )* + ]; ) } register_regex_member! { @@ -842,15 +819,6 @@ register_regex_member! { // ------------------------------ pub const YAML: &str = "yaml"; -pub const YAML_FUNCTION_NAMES: &[&str] = &[ - "encode", - "encode_all", - "decode", - "decode_all", - "dump_to_file", - "dump_all_to_file", - "validate", -]; macro_rules! register_yaml_member { ($($name:ident => $ty:expr)*) => ( pub const YAML_FUNCTION_TYPES: Lazy> = Lazy::new(|| { @@ -858,6 +826,9 @@ macro_rules! register_yaml_member { $( builtin_mapping.insert(stringify!($name).to_string(), $ty); )* builtin_mapping }); + pub const YAML_FUNCTION_NAMES: &[&str] = &[ + $( stringify!($name), )* + ]; ) } register_yaml_member! { @@ -1036,7 +1007,6 @@ register_yaml_member! { // ------------------------------ pub const JSON: &str = "json"; -pub const JSON_FUNCTION_NAMES: &[&str] = &["encode", "decode", "dump_to_file", "validate"]; macro_rules! register_json_member { ($($name:ident => $ty:expr)*) => ( pub const JSON_FUNCTION_TYPES: Lazy> = Lazy::new(|| { @@ -1044,6 +1014,9 @@ macro_rules! register_json_member { $( builtin_mapping.insert(stringify!($name).to_string(), $ty); )* builtin_mapping }); + pub const JSON_FUNCTION_NAMES: &[&str] = &[ + $( stringify!($name), )* + ]; ) } register_json_member! { @@ -1155,16 +1128,6 @@ register_json_member! { // ------------------------------ pub const CRYPTO: &str = "crypto"; -pub const CRYPTO_FUNCTION_NAMES: &[&str] = &[ - "md5", - "sha1", - "sha224", - "sha256", - "sha384", - "sha512", - "uuid", - "filesha256", -]; macro_rules! register_crypto_member { ($($name:ident => $ty:expr)*) => ( pub const CRYPTO_FUNCTION_TYPES: Lazy> = Lazy::new(|| { @@ -1172,6 +1135,9 @@ macro_rules! register_crypto_member { $( builtin_mapping.insert(stringify!($name).to_string(), $ty); )* builtin_mapping }); + pub const CRYPTO_FUNCTION_NAMES: &[&str] = &[ + $( stringify!($name), )* + ]; ) } register_crypto_member! { @@ -1553,7 +1519,6 @@ register_units_member! { // ------------------------------ pub const COLLECTION: &str = "collection"; -pub const COLLECTION_FUNCTION_NAMES: &[&str] = &["union_all"]; macro_rules! register_collection_member { ($($name:ident => $ty:expr)*) => ( pub const COLLECTION_FUNCTION_TYPES: Lazy> = Lazy::new(|| { @@ -1561,6 +1526,9 @@ macro_rules! register_collection_member { $( builtin_mapping.insert(stringify!($name).to_string(), $ty); )* builtin_mapping }); + pub const COLLECTION_FUNCTION_NAMES: &[&str] = &[ + $( stringify!($name), )* + ]; ) } register_collection_member! { @@ -1585,7 +1553,6 @@ register_collection_member! { // ------------------------------ pub const FILE: &str = "file"; -pub const FILE_FUNCTION_NAMES: &[&str] = &["read", "glob", "modpath", "workdir"]; macro_rules! register_file_member { ($($name:ident => $ty:expr)*) => ( pub const FILE_FUNCTION_TYPES: Lazy> = Lazy::new(|| { @@ -1593,6 +1560,9 @@ macro_rules! register_file_member { $( builtin_mapping.insert(stringify!($name).to_string(), $ty); )* builtin_mapping }); + pub const FILE_FUNCTION_NAMES: &[&str] = &[ + $( stringify!($name), )* + ]; ) } register_file_member! { @@ -1640,6 +1610,34 @@ register_file_member! { false, None, ) + exists => Type::function( + None, + Type::bool_ref(), + &[ + Parameter { + name: "filepath".to_string(), + ty: Type::str_ref(), + has_default: false, + }, + ], + r#"Whether this file path exists. Returns true if the path points at an existing entity. This function will traverse symbolic links to query information about the destination file."#, + false, + None, + ) + abs => Type::function( + None, + Type::str_ref(), + &[ + Parameter { + name: "filepath".to_string(), + ty: Type::str_ref(), + has_default: false, + }, + ], + r#"Returns the canonical, absolute form of the path with all intermediate components normalized and symbolic links resolved."#, + false, + None, + ) } pub const STANDARD_SYSTEM_MODULES: &[&str] = &[ diff --git a/test/grammar/builtins/file/exists/a.k b/test/grammar/builtins/file/exists/a.k new file mode 100644 index 000000000..d25d49e0f --- /dev/null +++ b/test/grammar/builtins/file/exists/a.k @@ -0,0 +1 @@ +a = 1 \ No newline at end of file diff --git a/test/grammar/builtins/file/exists/main.k b/test/grammar/builtins/file/exists/main.k new file mode 100644 index 000000000..a2d4fa8a0 --- /dev/null +++ b/test/grammar/builtins/file/exists/main.k @@ -0,0 +1,4 @@ +import file + +exists_result_0 = file.exists("a.k") +exists_result_1 = file.exists("b.k") diff --git a/test/grammar/builtins/file/exists/stdout.golden b/test/grammar/builtins/file/exists/stdout.golden new file mode 100644 index 000000000..5ae29c02a --- /dev/null +++ b/test/grammar/builtins/file/exists/stdout.golden @@ -0,0 +1,2 @@ +exists_result_0: true +exists_result_1: false