From 38cc9fcef1cbdf205aa47eed7870edb1d1cd7daf Mon Sep 17 00:00:00 2001 From: peefy Date: Mon, 8 Jul 2024 13:00:44 +0800 Subject: [PATCH] refactor: runtime api spec gen scripts Signed-off-by: peefy --- kclvm/Cargo.lock | 5 +- kclvm/makefile | 18 +- kclvm/runtime/Cargo.toml | 5 + kclvm/runtime/Makefile | 5 +- kclvm/runtime/readme.md | 7 - kclvm/runtime/scripts/gen-api-spec.rs | 307 ++++++++++++++ kclvm/runtime/src/_kclvm.bc | Bin 14492 -> 14484 bytes kclvm/runtime/src/_kclvm.h | 17 +- kclvm/runtime/src/_kclvm.ll | 4 +- .../tools/kclvm-runtime-gen-api/Makefile | 9 - .../tools/kclvm-runtime-gen-api/main.go | 374 ------------------ .../syntax/else_if_token/stderr.golden | 62 +++ .../syntax/else_if_token/stderr.golden.py | 20 - 13 files changed, 391 insertions(+), 442 deletions(-) delete mode 100644 kclvm/runtime/readme.md create mode 100644 kclvm/runtime/scripts/gen-api-spec.rs delete mode 100644 kclvm/runtime/tools/kclvm-runtime-gen-api/Makefile delete mode 100644 kclvm/runtime/tools/kclvm-runtime-gen-api/main.go create mode 100644 test/grammar/syntax/else_if_token/stderr.golden delete mode 100644 test/grammar/syntax/else_if_token/stderr.golden.py diff --git a/kclvm/Cargo.lock b/kclvm/Cargo.lock index 3c87571ea..c3464c392 100644 --- a/kclvm/Cargo.lock +++ b/kclvm/Cargo.lock @@ -2020,6 +2020,7 @@ dependencies = [ "unic-ucd-category", "unicode-casing", "uuid", + "walkdir", ] [[package]] @@ -2227,9 +2228,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.21" +version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "lsp-server" diff --git a/kclvm/makefile b/kclvm/makefile index 61c4b9074..9e119a7ee 100644 --- a/kclvm/makefile +++ b/kclvm/makefile @@ -12,18 +12,18 @@ gen-runtime-api: make -C ./runtime gen-api-spec make fmt -# Install the wasm target +# Install the wasm32-unknown-unknown target install-rustc-wasm: rustup target add wasm32-unknown-unknown +# Install the wasm-wasi target +install-rustc-wasm-wasi: + rustup target add wasm32-wasi + # Install python3 pytest install-pytest: python3 -mpip install --user -U pytest pytest-html pytest-xdist -# Install kclvm-py -install-kclvm-py: - python3 -mpip install --user -U kclvm - # ------------------------ # Compile and run # ------------------------ @@ -82,19 +82,19 @@ codecov-lcov: cargo llvm-cov --features llvm --lcov --output-path $(PWD)/.kclvm_cov/lcov.info -r --workspace --ignore-filename-regex gpyrpc.rs -- --nocapture # Test runtime libaries using python functions -test-runtime: install-kclvm-py install-pytest +test-runtime: install-pytest cd ./tests/test_units && PYTHONPATH=./../../tests/test_units/runtime python3 -m pytest -vv || { echo 'kclvm/tests/test_units failed' ; exit 1; } # E2E grammar tests. -test-grammar: install-kclvm-py install-pytest +test-grammar: install-pytest cd tests/integration/grammar && python3 -m pytest -v -n 5 # E2E grammar tests with the fast evaluator -test-grammar-evaluator: install-kclvm-py install-pytest +test-grammar-evaluator: install-pytest cd tests/integration/grammar && KCL_FAST_EVAL=1 python3 -m pytest -v -n 5 # E2E konfig tests. -test-konfig: install-kclvm-py install-pytest +test-konfig: install-pytest cd tests/integration/konfig && python3 -m pytest -v -n 5 # Parser fuzz. diff --git a/kclvm/runtime/Cargo.toml b/kclvm/runtime/Cargo.toml index ec7347c05..5833cf5f4 100644 --- a/kclvm/runtime/Cargo.toml +++ b/kclvm/runtime/Cargo.toml @@ -30,3 +30,8 @@ num-integer = "0.1.44" glob = "0.3.0" uuid = { version = "1.7.0", features = ["serde", "v4"] } handlebars = "5.1.2" +walkdir = "2.5.0" + +[[bin]] +name = "gen-api-spec" +path = "scripts/gen-api-spec.rs" diff --git a/kclvm/runtime/Makefile b/kclvm/runtime/Makefile index 412cc61d2..c1c27b8be 100644 --- a/kclvm/runtime/Makefile +++ b/kclvm/runtime/Makefile @@ -1,17 +1,16 @@ default: make gen-api-spec - cargo test gen-api-spec: mkdir -p target cargo clean -q - KCLVM_RUNTIME_GEN_API_SPEC= cargo build > ./src/_kclvm_api_spec.rs.tmp + KCLVM_RUNTIME_GEN_API_SPEC= cargo build -r > ./src/_kclvm_api_spec.rs.tmp echo "// Copyright The KCL Authors. All rights reserved.\n" > ./src/_kclvm_api_spec.rs echo "// Auto generated by command, DONOT EDIT!!!\n" >> ./src/_kclvm_api_spec.rs cat ./src/_kclvm_api_spec.rs.tmp >> ./src/_kclvm_api_spec.rs rm ./src/_kclvm_api_spec.rs.tmp - make -C ./tools/kclvm-runtime-gen-api + cargo run -r --bin gen-api-spec diff --git a/kclvm/runtime/readme.md b/kclvm/runtime/readme.md deleted file mode 100644 index 1ff43103d..000000000 --- a/kclvm/runtime/readme.md +++ /dev/null @@ -1,7 +0,0 @@ -# KCLVM - runtime - -KCLVM runtime library. - -- run test: `make` -- regenerate llvm-ir file: `make gen-api-spec` -- lint code: `cargo clippy` diff --git a/kclvm/runtime/scripts/gen-api-spec.rs b/kclvm/runtime/scripts/gen-api-spec.rs new file mode 100644 index 000000000..28513805b --- /dev/null +++ b/kclvm/runtime/scripts/gen-api-spec.rs @@ -0,0 +1,307 @@ +use std::collections::HashMap; +use std::error::Error; +use std::fs; +use std::process; +use std::process::Command; +use std::process::ExitStatus; +use walkdir::WalkDir; + +const ROOT: &str = "./src"; +const C_API_FILE: &str = "./src/_kclvm.h"; +const LL_API_FILE: &str = "./src/_kclvm.ll"; +const RUST_API_ENUM: &str = "./src/_kclvm.rs"; +const RUST_API_ADDR: &str = "./src/_kclvm_addr.rs"; + +#[derive(Debug, Default)] +struct ApiSpec { + file: String, + line: usize, + name: String, + spec_c: String, + spec_ll: String, + is_type: bool, +} + +fn main() -> Result<(), Box> { + std::env::set_var("KCLVM_RUNTIME_GEN_API_SPEC", "1"); + let specs = load_all_api_spec(ROOT); + let src = gen_c_api(&specs); + fs::write(C_API_FILE, src).unwrap_or_else(|err| { + eprintln!("Failed to write C API file: {}", err); + process::exit(1); + }); + + let src = gen_ll_api(&specs); + fs::write(LL_API_FILE, src).unwrap_or_else(|err| { + eprintln!("Failed to write LLVM API file: {}", err); + process::exit(1); + }); + + let src = gen_rust_api_enum(&specs); + fs::write(RUST_API_ENUM, src).unwrap_or_else(|err| { + eprintln!("Failed to write Rust API Enum file: {}", err); + process::exit(1); + }); + + let src = gen_rust_api_addr(&specs); + fs::write(RUST_API_ADDR, src).unwrap_or_else(|err| { + eprintln!("Failed to write Rust API Addr file: {}", err); + process::exit(1); + }); + + run_llvm_as(LL_API_FILE)?; + run_cargo_fmt()?; + Ok(()) +} + +fn load_all_api_spec(root: &str) -> Vec { + let mut specs: HashMap = HashMap::new(); + let api_spec_prefix_name = "// api-spec:"; + let api_spec_prefix_c = "// api-spec(c):"; + let api_spec_prefix_ll = "// api-spec(llvm):"; + + for entry in WalkDir::new(root).into_iter().filter_map(|e| e.ok()) { + let path = entry.path(); + if path.is_dir() + || !path + .to_str() + .expect(&format!("{path:?} not found")) + .ends_with(".rs") + { + continue; + } + let data = fs::read_to_string(path).expect(&format!("{path:?} not found")); + let mut spec = ApiSpec::default(); + + for (i, line) in data.lines().enumerate() { + let line = line.trim(); + + if line.starts_with(api_spec_prefix_name) { + spec.file = path.display().to_string(); + spec.line = i + 1; + spec.name = line + .trim_start_matches(api_spec_prefix_name) + .trim() + .to_string(); + spec.is_type = spec.name.ends_with("_t"); + } else if line.starts_with(api_spec_prefix_c) { + if !spec.spec_c.is_empty() { + spec.spec_c.push(' '); + } + spec.spec_c + .push_str(line.trim_start_matches(api_spec_prefix_c).trim()); + } else if line.starts_with(api_spec_prefix_ll) { + if !spec.spec_ll.is_empty() { + spec.spec_ll.push(' '); + } + spec.spec_ll + .push_str(line.trim_start_matches(api_spec_prefix_ll).trim()); + } else { + if !spec.name.is_empty() { + if let Some(existing) = specs.get(&spec.name) { + eprintln!( + "WARN: {}:{} {} api-spec exists ({}:{})", + path.display(), + i + 1, + spec.name, + existing.file, + existing.line + ); + } + specs.insert(spec.name.clone(), spec); + } + spec = ApiSpec::default(); + } + } + } + + let mut spec_list: Vec = specs.into_values().collect(); + spec_list.sort_by(|a, b| a.name.cmp(&b.name)); + spec_list +} + +fn gen_c_api(specs: &[ApiSpec]) -> String { + let mut buf = String::new(); + + buf.push_str("// Copyright The KCL Authors. All rights reserved.\n\n"); + buf.push_str("// Auto generated, DONOT EDIT!!!\n\n"); + buf.push_str("#pragma once\n\n"); + buf.push_str("#ifndef _kclvm_h_\n#define _kclvm_h_\n\n"); + buf.push_str("#include \n#include \n#include \n\n"); + buf.push_str("#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n"); + + buf.push_str("// please keep same as 'kclvm/runtime/src/kind/mod.rs#Kind'\n\n"); + buf.push_str("enum kclvm_kind_t {\n"); + buf.push_str(" Invalid = 0,\n"); + buf.push_str(" Undefined = 1,\n"); + buf.push_str(" None = 2,\n"); + buf.push_str(" Bool = 3,\n"); + buf.push_str(" Int = 4,\n"); + buf.push_str(" Float = 5,\n"); + buf.push_str(" Str = 6,\n"); + buf.push_str(" List = 7,\n"); + buf.push_str(" Dict = 8,\n"); + buf.push_str(" Schema = 9,\n"); + buf.push_str(" Error = 10,\n"); + buf.push_str(" Any = 11,\n"); + buf.push_str(" Union = 12,\n"); + buf.push_str(" BoolLit = 13,\n"); + buf.push_str(" IntLit = 14,\n"); + buf.push_str(" FloatLit = 15,\n"); + buf.push_str(" StrLit = 16,\n"); + buf.push_str(" Func = 17,\n"); + buf.push_str(" Max = 18,\n"); + buf.push_str("};\n\n"); + + for spec in specs { + if spec.is_type { + buf.push_str(&spec.spec_c); + buf.push_str("\n\n"); + } + } + + for spec in specs { + if !spec.is_type { + buf.push_str(&spec.spec_c); + buf.push_str("\n\n"); + } + } + + buf.push_str("#ifdef __cplusplus\n} // extern \"C\"\n#endif\n\n"); + buf.push_str("#endif // _kclvm_h_\n"); + + fmt_code(&buf) +} + +fn gen_ll_api(specs: &[ApiSpec]) -> String { + let mut buf = String::new(); + + buf.push_str("; Copyright The KCL Authors. All rights reserved.\n\n"); + buf.push_str("; Auto generated, DONOT EDIT!!!\n\n"); + + for spec in specs { + if spec.is_type { + buf.push_str(&spec.spec_ll); + buf.push_str("\n\n"); + } + } + + for spec in specs { + if !spec.is_type { + buf.push_str(&spec.spec_ll); + buf.push_str("\n\n"); + } + } + + buf.push_str( + "define void @__kcl_keep_link_runtime(%kclvm_value_ref_t* %_a, %kclvm_context_t* %_b) {\n", + ); + buf.push_str(" call %kclvm_value_ref_t* @kclvm_value_None(%kclvm_context_t* %_b)\n"); + buf.push_str(" ret void\n"); + buf.push_str("}\n"); + + fmt_code(&buf) +} + +fn gen_rust_api_enum(specs: &[ApiSpec]) -> String { + let mut buf = String::new(); + + buf.push_str("// Copyright The KCL Authors. All rights reserved.\n\n"); + buf.push_str("// Auto generated, DONOT EDIT!!!\n\n"); + + // Enum ApiType + buf.push_str("#[allow(dead_code, non_camel_case_types)]\n"); + buf.push_str("#[derive(Clone, PartialEq, Eq, Debug, Hash)]\n"); + buf.push_str("pub enum ApiType {\n"); + buf.push_str(" Value,\n"); + buf.push_str("}\n"); + buf.push('\n'); + buf.push_str("impl std::fmt::Display for ApiType {\n"); + buf.push_str(" fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {\n"); + buf.push_str(" match self {\n"); + buf.push_str(" ApiType::Value => write!(f, \"{:?}\", \"api::kclvm::Value\"),\n"); + buf.push_str(" }\n"); + buf.push_str(" }\n"); + buf.push_str("}\n"); + buf.push('\n'); + buf.push_str("impl ApiType {\n"); + buf.push_str(" #[allow(dead_code)]\n"); + buf.push_str(" pub fn name(&self) -> String {\n"); + buf.push_str(" format!(\"{self:?}\")\n"); + buf.push_str(" }\n"); + buf.push_str("}\n"); + buf.push('\n'); + // Enum ApiFunc + buf.push_str("#[allow(dead_code, non_camel_case_types)]\n"); + buf.push_str("#[derive(Clone, PartialEq, Eq, Debug, Hash)]\n"); + buf.push_str("pub enum ApiFunc {\n"); + + for spec in specs { + if !spec.is_type { + buf.push_str(" "); + buf.push_str(&spec.name); + buf.push_str(",\n"); + } + } + + buf.push_str("}\n"); + buf.push('\n'); + buf.push_str("impl std::fmt::Display for ApiFunc {\n"); + buf.push_str(" fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {\n"); + buf.push_str(" write!(f, \"{self:?}\")\n"); + buf.push_str(" }\n"); + buf.push_str("}\n"); + buf.push('\n'); + buf.push_str("impl ApiFunc {\n"); + buf.push_str(" #[allow(dead_code)]\n"); + buf.push_str(" pub fn name(&self) -> String {\n"); + buf.push_str(" format!(\"{self:?}\")\n"); + buf.push_str(" }\n"); + buf.push_str("}\n"); + + fmt_code(&buf) +} + +fn gen_rust_api_addr(specs: &[ApiSpec]) -> String { + let mut buf = String::new(); + + buf.push_str("// Copyright The KCL Authors. All rights reserved.\n\n"); + buf.push_str("// Auto generated, DONOT EDIT!!!\n\n"); + + buf.push_str("#[allow(dead_code)]\n"); + buf.push_str("pub fn _kclvm_get_fn_ptr_by_name(name: &str) -> u64 {\n"); + buf.push_str(" match name {\n"); + + for spec in specs { + if !spec.is_type { + buf.push_str(" \""); + buf.push_str(&spec.name); + buf.push_str("\" => crate::"); + buf.push_str(&spec.name); + buf.push_str(" as *const () as u64,\n"); + } + } + + buf.push_str(" _ => panic!(\"unknown {name}\"),\n"); + buf.push_str(" }\n"); + buf.push_str("}\n"); + + fmt_code(&buf) +} + +fn fmt_code(s: &str) -> String { + s.split("\n\n\n") + .collect::>() + .join("\n\n") + .trim() + .to_string() + + "\n" +} + +fn run_llvm_as(file_path: &str) -> Result { + Command::new("llvm-as").arg(file_path).status() +} + +fn run_cargo_fmt() -> Result { + Command::new("cargo").arg("fmt").status() +} diff --git a/kclvm/runtime/src/_kclvm.bc b/kclvm/runtime/src/_kclvm.bc index a9ffd1ab75ef8a541b3482f3eb2ba3da7f92d628..2fc81056dbcc99dd43adc14b65abfdea0630351b 100644 GIT binary patch literal 14484 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 C$#n7n literal 14492 zcmb7J3tUvyy5IAFLBIidC>r2EnmE1?wIcyJfEAJ&J}@n9vzgfg8|Sf^2LinY2O2c( zT0wcU2bP|aUY7bhmX;#oRimzTqoXJ5U_Mf_Qcre!Xq|7rhCSaN?(cW!rwr>`-}=`7 zd#-OSii-DtJtK)AA_#)0jLjZXy6i)%{r8<@%mUwB70@zb3F1F=1QDaoAk;7(4*zvc zH$Pc;SUV>&J}37nRdejvh^Ue2+Q%z>hC9?nPsJ2zhvg*Aj7qsXI%joj341W(=Gh5> zb@7EysV#@2-bpeP-`Q$7qRLs_oMOx}ZkYPe_T^6+4j%@&YYYVO8hqzuMnxMeE!xB} zTbkj=>E_KFk`m@_SQpc*ofqHQ6SY58RiyggtOEY6?vi28to?OD z#pc#onQI>{Y9f-8)V}@uefnt1R8e6X(n1*G<2zc4h?Jvzhix_Iy*~C6yBw4XjA)49k2LJr6A5wVajxCJ4|C* zi0t^RjHfxFDe?@sZj{^}&UY5gL_iypCvU^1^W>UV-;p(c42e){7i;~71f$v%KP)-J z(7NtuMZCpSLKE3hhOHSskdwV&(MZ_+{5Ed;w50M#!moeMsPz>FROQJklkY8nZ2&VY zYl(+X$D0d@_>`2CvU_u3^H|va{Oc*OePpCMX-O=h*7y@tqb96V0r)22zpA}Gg44jX z-()fwe4j*Df>GgPFfrrCgCk}wP<=FI$S1|u6Qi}&Z>A7hn_4~g^Cep1*2W0|m1>jE z=Tr5x`_`XZt1|7s1?=agvkg%ld-fzz+crLG(2i5zGVV9dd5?~|naFy3OruuKp^1## zd9PNZzBs|JQYGF8|v%I-LtsU3NYo*ElfS{kd(+A$sM2OD#{!)NER zSdAJSqPaLx<5Q^~)@va=iBTDI_2ZuX?yT#Bb62l?w>YNEJl;p0<1 zwz#*A;BrX(WbfZ_aZ`dp8p3yE%EBXsn5QP`4K0%MUd33GY*}pfmc~Gqic3fFQ{l@< zE-4ujFOA__6T8h)RO*vaQYuRB7`{l&t00i~6UCi-S}~-}cVbA!zbGL6I1EEl4;zml zwXd6vAsrf{fHZC?f@EB>21B|Q-Ht42eBj*(WF_M(7*ggYY^CzA6p-dtVMy(H*hfq~1CKS*dRlgRS(<5e&(@5L>D9rS~zU6Xnk!D_z|6E{1fz z9YczKXCi{s{sfI7ottFiH zY$e*S!WK9>RHM*td?Yrek&Jx{qq>&DVk1=M^kW5g(JTg^`Efr6wrf+D!Vb6lad7sv zMlQxCy=kZ-sH#UT9*Q#kx9J_}23e{@Vd<$c-C>fEplBHXZg|coBSAr+-!4p9jM&~k z;oF1QX8f&bl`6E98S6CDb|W_LzNTjpTjygMrzW&g^`+`w)S)W0RG**C_ZK2OC}@3o zy00Qb*^JNV-ye#yo=NlEgsd?)&)|liAPKr*up<6hV~N38Z)xm zRHIO>D25nJ?#h_#rl=LvOBq)Bug_XWYGp3`L37-Tev$tzn-@2QZp z`WLqLV|bg#SLhI%YtimAnCxfs|(%j$7t?%H9% zz<#Sz;gq@d+3K;;$OXogs>BF`%qd-gp=)>nEnzQN&f?fr^v7~8oOyYIu;j8hiBjj(mTG{TsVqBr@gn3T~d zde>f4rfSdc3ZJgM(J~GlqkVtG%%6y)86yJ5;V44R`isxtTxjg>dPkw`ss3X)7nam^ zoX5GaZ)VvJtZYN-%geB`bM*5kA$X;?1STOZ%J0|TgCq09)aP+zcIGOIxyP-jneTl| z;K;oC-(5ImdS33vDRc2Io#F)Fq%T9jI%lORfW3K}0$8Khr%0LaE{{RE@Xg;9xxDLL zKQ7V6ssQ$T@;~&rr|tYe32a+lK28L7l_C+g{@9N#cH60pp%{PH6;mXZR^1Tq$8P#L zzXG!@Z#;~py>M+i-ZbHR6>dtme(A?kUPnZ@fX_ays^p?$2XT z2zCD1^gAx6J%&$PG^m`O+)(DPMVcm0PFRwQG(DO&1m9?q=Oo;ZI=9Z3#%y;ZX?-ga zmfVJm*RN4+;$9G z_=r)Zh_`z)v4v;6t;O+HV_AdCLh{E6xGWgo9jkD?_ija5D1BCueJ3U>faQ=1VBUQS zU>BQ*U|@Yi6EU#PX}5Gdh&`2-*mpbf)Y|qTuZ{K%IDmi-s^_EGpU0VGH0Ypesxp7W zp89oKVT%^Uo8`I7cdF6x&Cbgos|sz}JNMnv@d$>uGV!xH2%d58nyj%1-q?R?74Q;j zi!Ne#pU%AU28MU&`HlBscy;qlH&A^rE*jUVfcIA7vAYqxny-f75?%gb;sbLL+r@K3 zaP8{*GI2RRV*17%HJ~Fh`Ff(_dY&}#AZF_uHC!QW(L|%7N1ZbKDSTfzn)Y}Nw(yLn zdTvcb0dVz*`tczKSx`W#o}f?Rqb>8}1Nh7xyQu{y*V_EYJ8wa5ZGS1kgEuYx^czL5 za;kd4JGfW*$IkxaxL4VB-(p-J9@?d78;-2Z!1W>XgyO-C-qC_D{%h?qxSwgiFnk5} z>6J-}rzq4uq1{QrK69e0NS^+HjlNfxMw!bz)@rJWv$`*WrUwS}sYrg)0;xO%cNa4za z-_@_+UiZSoO`qcUvFzKexc6NkZMmpw855@OeF0Ui_LNZz?m_upqaXUlI27Ky);@-_ zpmW4}To&33MvcUm+>2w^Pwl{39NDVWV)6eRR&?yAndKf_+-^*tj4MO=x>3n^-=lMf zK8`QfJ+CTWl{?GV8&TD2-#rR9W}OW)IPa4{j}Jk^aEXKpKMOGW=HUB{+oI=1&50Z)@cfQ>(_Z$-GfoOhLQlw z>Ka*1U44Kx1V;7_(_h-4Kb0Nl$c{UGS%0}qKP~=X+SeJW$1~CnQ0dm}HFMC>(R_p#!9dN-*;mxUMHmCOTKTlGrM>A3nHl-bTfcz z-CwZNe^Yb!%yq@Nz1{h{yK)bAgO2&VB|B@QbbzWB47fBf^2)XUg=yWZ(SFB`WnmQ`+%UBQ9m6oy$l&n2`n^JfAVz zYIq@UZ*jqHO>Ub%w|D7Y@IENp2sldut5_XDY)c`Ckq~1s(XK4;ovv{yyAk-i!AiNu zx>uh|J+yh~`9dzVK&)Vs;nPo7=)WxkQ^%d*3?BDwnf|Bkz9wBm79R=q0nmc8!&3J7 z?wLDPd0YGiZ5r6)Q)t5?;ak_6zr~;TJUCcW(BaPqXK(1{9(*YSK@5TKL~U1VA^dqX zWX!*$=U(NT}W@7$->0DpFZ?;L%6X7gTkYaB;}&k9JIb+Ac-rp;`F z@k+C;&Q4NpH|_EWzgJRj`qt^Bg*H1abO?!d$Vgts=3yKpRp}OaB!bOGdR$&V=#=A;m*nywFB#W)ZL$u&V%f0gE@v(YT%;n&N`ZP(N+cpDJM*rb$hLY%(Awyy12r-141gS-Cb_h7S4#S zK`;-(&XaA7gGSYaQ^f6|T%JKKB3{V3=dZo9DvBH^cbr4USV8N$w_gR)CLkk0}?X=R{Z!nATNH_JJX zG)v_hueCYN)Ijyav!E4cfbfDv>x7?N<#esIFk-IC#d3jR_K(~oJVBB}s{KKVhcT}dlW2hEv``J=O4>@nfhE_Uad3w}6jl$(LRs=i z^~y3RtIT5D`AnK^G$s0gA6H3dmNbIu?{P^8xD~)5w|kI}mrPbRkOT3+&s9@y1;2n> zRErZTD&loOl@=qMUo6rwYDhOIpDq_;q4|uKNm@xaNH*jI2m1tGoSk+_XDL4x3axCl zo3hd(7&$eJ%3fCHQ*I}LK*IhCb$R$ADlQcVS}$P)2aR-&@&vP3p7?>hHt__y9u6(J zv?`mkQb5bk+XvE07|T;spw!9OT{I;|D?i5#!RK-gcd%LDIYJUwptu+*yx|uY<#9rv z;dODg5H<>-%A6Ub%asfg!OKCr1c?r=Udu$(xSvH4g?51S>6Wo1Q5gw z_>t=&NlNAo8G#&VaOG54ODiV_yEr)!3Y&mMPLzi{PnTt+Fdk^i`0>CY&kutMD~(8b zv&s|Y*~SxsNx_d;rxCDESJoIh-B*?T6>7GK&Gsj~F*t2*O3i zz_=NQ*y4*U4od9i`LWGeCF6$C)NC}CLxg#;-t&v$1eD7Tw)Fg@yH>iJIiQBjDdVic zIK05@pH}hTyzy(52vo3h0-l2ahXWj#K;u5 z!0BeO84?ICTGp%!BsZM6p-i&Q+66Z-u3>HA6sbbtfvA)9 zsp1r0um`0F+iJJj$-?Pqv5*{Wshbg~@*_f^1WTVVL{ftF$V1z~2OgTF>uIxBDhxqt zwFin6?S^}?Xh4W{s9g{}cL|ml7&C})Hy&e#d5B>iW)PD-xJ4OeSd1hr#tdR*4N4G$ zHaPYQ0t5#X1s`dI@oac0;*V=N(`@Kwb@2Uo$SRRWdZGAM zk*pL~!iqW4JA*Ks8+^PO7)v#HfFkC$K$suAFbU&D{1r)#U{UCnFvKVp2Oqlx8Rd`& zkkryUibRwy$-8TC@$MuDBreJF$$b?9>$ch>whO|o3Toq#`DXATo6Q!O* zpm8P)#qVUf$|VQGQQ+nuo?6L3uNk_J$j{B#+|`UVM19$0C=%I(>;GC+A9k6A5nFvh zEm0WXVv*tJpy3IlBpmr+sKIV1M7rB6-dBRu@WvR_5Zr`98;%&(0NjL9d8KlLDXmmk zsjN~_q$C_c4(?DH=qm)}B|6tD%MB>@+z{Vlg%{Yx^HeH0@)hC~f26~E3cPlO%-R^~ z{Zo|05yE5u;C7osa!R0tVHMSpU&jR5ArnHA;qXeGQji6D;jl~jYXi?ESHSC_Tn(fR zR|SC#Py61G@*$8>1rdnQ=ONbM+r9t|&Q7>f20J?*j{JrxBVaD>+6fCeM{_r00l&bn zxRLT?`HfUYKym>We@!JxkO -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -// please keep same as 'kclvm/runtime/src/kind/mod.rs#Kind' - -enum kclvm_kind_t { - Invalid = 0, - - // only for value - - Undefined = 1, - None = 2, - - // for value & type - - Bool = 3, - Int = 4, - Float = 5, - Str = 6, - List = 7, - Dict = 8, - - Schema = 9, - Error = 10, - - // only for type - - Any = 11, - Union = 12, - - BoolLit = 13, - IntLit = 14, - FloatLit = 15, - StrLit = 16, - - Func = 17, - - // max num - - Max = 18, -}; - -{{range $_, $spec := $specList}} -{{if ($spec.IsType)}}{{$spec.SpecC}}{{end}} -{{end}} - -{{range $_, $spec := $specList}} -{{if (not $spec.IsType)}}{{$spec.SpecC}}{{end}} -{{end}} - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // _kclvm_h_ -` - -// ---------------------------------------------------------------------------- - -const tmplLLApi = ` -{{$specList := .}} - -; Copyright The KCL Authors. All rights reserved. - -; Auto generated, DONOT EDIT!!! - -{{range $_, $spec := $specList}} -{{if ($spec.IsType)}}{{$spec.SpecLL}}{{end}} -{{end}} - -{{range $_, $spec := $specList}} -{{if (not $spec.IsType)}}{{$spec.SpecLL}}{{end}} -{{end}} - -define void @__kcl_keep_link_runtime(%kclvm_value_ref_t* %_a, %kclvm_context_t* %_b) { - call %kclvm_value_ref_t* @kclvm_value_None(%kclvm_context_t* %_b) - ret void -} -` - -// ---------------------------------------------------------------------------- - -const tmplRustEnum = ` -{{$specList := .}} - -// Copyright The KCL Authors. All rights reserved. - -// Auto generated, DONOT EDIT!!! - -#[allow(dead_code, non_camel_case_types)] -#[derive(Clone, PartialEq, Eq, Debug, Hash)] -pub enum ApiType { - Value, -} - -impl std::fmt::Display for ApiType { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - match self { - ApiType::Value => write!(f, "{:?}", "api::kclvm::Value"), - } - } -} - -impl ApiType { - #[allow(dead_code)] - pub fn name(&self) -> String { - format!("{self:?}") - } -} - -#[allow(dead_code, non_camel_case_types)] -#[derive(Clone, PartialEq, Eq, Debug, Hash)] -pub enum ApiFunc { - {{range $_, $spec := $specList}}{{if (not $spec.IsType)}} - {{- $spec.Name}}, - {{end}}{{end}} -} - -impl std::fmt::Display for ApiFunc { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - write!(f, "{self:?}") - } -} - -impl ApiFunc { - #[allow(dead_code)] - pub fn name(&self) -> String { - format!("{self:?}") - } -} -` - -// ---------------------------------------------------------------------------- - -const tmplRustAddr = ` -{{$specList := .}} - -// Copyright The KCL Authors. All rights reserved. - -// Auto generated, DONOT EDIT!!! - -#[allow(dead_code)] -pub fn _kclvm_get_fn_ptr_by_name(name: &str) -> u64 { - match name { - {{- range $_, $spec := $specList -}}{{if (not $spec.IsType)}} - "{{$spec.Name}}" => crate::{{$spec.Name}} as *const () as u64, - {{- end}}{{end}} - _ => panic!("unknown {name}"), - } -} -` - -// ---------------------------------------------------------------------------- diff --git a/test/grammar/syntax/else_if_token/stderr.golden b/test/grammar/syntax/else_if_token/stderr.golden new file mode 100644 index 000000000..6a69a43f5 --- /dev/null +++ b/test/grammar/syntax/else_if_token/stderr.golden @@ -0,0 +1,62 @@ +error[E1001]: InvalidSyntax + --> ${CWD}/main.k:3:1 + | +3 | else if False: + | 'else if' here is invalid in KCL, consider using the 'elif' keyword + | + +error[E1001]: InvalidSyntax + --> ${CWD}/main.k:3:9 + | +3 | else if False: + | ^ expected one of [":"] got identifier + | + +error[E1001]: InvalidSyntax + --> ${CWD}/main.k:3:14 + | +3 | else if False: + | ^ expected one of ["identifier", "literal", "(", "[", "{"] got : + | + +error[E1001]: InvalidSyntax + --> ${CWD}/main.k:3:14 + | +3 | else if False: + | ^ expected one of ["any", "bool", "int", "float", "str", "True", "False", "identifier", "literal", "[", "{", ")"] got newline + | + +error[E1001]: InvalidSyntax + --> ${CWD}/main.k:4:5 + | +4 | b = 1 + | ^ expected one of ["="] got indent + | + +error[E1001]: InvalidSyntax + --> ${CWD}/main.k:4:5 + | +4 | b = 1 + | ^ expected one of ["identifier"] got indent + | + +error[E1001]: InvalidSyntax + --> ${CWD}/main.k:4:5 + | +4 | b = 1 + | ^ unexpected token 'indent' + | + +error[E1001]: InvalidSyntax + --> ${CWD}/main.k:4:9 + | +4 | b = 1 + | ^ unexpected token 'dedent' + | + +error[E2L23]: CompileError + --> ${CWD}/main.k:3:14 + | +3 | else if False: + | ^ missing target in the assign statement + | diff --git a/test/grammar/syntax/else_if_token/stderr.golden.py b/test/grammar/syntax/else_if_token/stderr.golden.py deleted file mode 100644 index 902f563d4..000000000 --- a/test/grammar/syntax/else_if_token/stderr.golden.py +++ /dev/null @@ -1,20 +0,0 @@ -import sys -import kclvm.kcl.error as kcl_error -import os - -cwd = os.path.dirname(os.path.realpath(__file__)) - -kcl_error.print_kcl_error_message( - kcl_error.get_exception( - err_type=kcl_error.ErrType.CompileError_TYPE, - file_msgs=[ - kcl_error.ErrFileMsg( - filename=cwd + "/main.k", - line_no=3, - col_no=6, - ) - ], - arg_msg="'else if' here is invalid in KCL, consider using the 'elif' keyword", - file=sys.stdout, - ) -)