@tishlang/tish-format 1.0.12 → 1.0.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (164) hide show
  1. package/Cargo.toml +49 -0
  2. package/LICENSE +13 -0
  3. package/README.md +138 -0
  4. package/bin/tish-format +0 -0
  5. package/crates/js_to_tish/Cargo.toml +11 -0
  6. package/crates/js_to_tish/README.md +18 -0
  7. package/crates/js_to_tish/src/error.rs +55 -0
  8. package/crates/js_to_tish/src/lib.rs +11 -0
  9. package/crates/js_to_tish/src/span_util.rs +35 -0
  10. package/crates/js_to_tish/src/transform/expr.rs +610 -0
  11. package/crates/js_to_tish/src/transform/stmt.rs +503 -0
  12. package/crates/js_to_tish/src/transform.rs +60 -0
  13. package/crates/tish/Cargo.toml +54 -0
  14. package/crates/tish/src/cargo_native_registry.rs +32 -0
  15. package/crates/tish/src/cli_help.rs +565 -0
  16. package/crates/tish/src/main.rs +781 -0
  17. package/crates/tish/src/repl_completion.rs +200 -0
  18. package/crates/tish/tests/cargo_example_compile.rs +67 -0
  19. package/crates/tish/tests/fixtures/cargo_example_project/Cargo.toml +3 -0
  20. package/crates/tish/tests/fixtures/cargo_example_project/crates/demo-shim/Cargo.toml +11 -0
  21. package/crates/tish/tests/fixtures/cargo_example_project/crates/demo-shim/src/lib.rs +12 -0
  22. package/crates/tish/tests/fixtures/cargo_example_project/package.json +10 -0
  23. package/crates/tish/tests/fixtures/cargo_example_project/src/main.tish +3 -0
  24. package/crates/tish/tests/integration_test.rs +1095 -0
  25. package/crates/tish/tests/run_optimize_stdout_parity.rs +50 -0
  26. package/crates/tish/tests/shortcircuit.rs +65 -0
  27. package/crates/tish_ast/Cargo.toml +9 -0
  28. package/crates/tish_ast/src/ast.rs +620 -0
  29. package/crates/tish_ast/src/lib.rs +5 -0
  30. package/crates/tish_build_utils/Cargo.toml +11 -0
  31. package/crates/tish_build_utils/src/lib.rs +577 -0
  32. package/crates/tish_builtins/Cargo.toml +20 -0
  33. package/crates/tish_builtins/src/array.rs +441 -0
  34. package/crates/tish_builtins/src/construct.rs +159 -0
  35. package/crates/tish_builtins/src/globals.rs +213 -0
  36. package/crates/tish_builtins/src/helpers.rs +35 -0
  37. package/crates/tish_builtins/src/lib.rs +16 -0
  38. package/crates/tish_builtins/src/math.rs +89 -0
  39. package/crates/tish_builtins/src/object.rs +36 -0
  40. package/crates/tish_builtins/src/string.rs +647 -0
  41. package/crates/tish_builtins/src/symbol.rs +83 -0
  42. package/crates/tish_bytecode/Cargo.toml +17 -0
  43. package/crates/tish_bytecode/src/chunk.rs +96 -0
  44. package/crates/tish_bytecode/src/compiler.rs +1760 -0
  45. package/crates/tish_bytecode/src/encoding.rs +100 -0
  46. package/crates/tish_bytecode/src/lib.rs +19 -0
  47. package/crates/tish_bytecode/src/opcode.rs +142 -0
  48. package/crates/tish_bytecode/src/peephole.rs +189 -0
  49. package/crates/tish_bytecode/src/serialize.rs +163 -0
  50. package/crates/tish_bytecode/tests/break_continue_bytecode.rs +44 -0
  51. package/crates/tish_bytecode/tests/constant_folding.rs +84 -0
  52. package/crates/tish_bytecode/tests/sort_optimization.rs +31 -0
  53. package/crates/tish_compile/Cargo.toml +26 -0
  54. package/crates/tish_compile/src/codegen.rs +5332 -0
  55. package/crates/tish_compile/src/infer.rs +292 -0
  56. package/crates/tish_compile/src/lib.rs +164 -0
  57. package/crates/tish_compile/src/resolve.rs +1388 -0
  58. package/crates/tish_compile/src/types.rs +501 -0
  59. package/crates/tish_compile_js/Cargo.toml +18 -0
  60. package/crates/tish_compile_js/examples/jsx_vdom_smoke.tish +8 -0
  61. package/crates/tish_compile_js/src/codegen.rs +871 -0
  62. package/crates/tish_compile_js/src/error.rs +20 -0
  63. package/crates/tish_compile_js/src/lib.rs +26 -0
  64. package/crates/tish_compile_js/src/tests_jsx.rs +350 -0
  65. package/crates/tish_compiler_wasm/Cargo.toml +21 -0
  66. package/crates/tish_compiler_wasm/src/lib.rs +57 -0
  67. package/crates/tish_compiler_wasm/src/resolve_virtual.rs +473 -0
  68. package/crates/tish_core/Cargo.toml +26 -0
  69. package/crates/tish_core/src/console_style.rs +160 -0
  70. package/crates/tish_core/src/json.rs +387 -0
  71. package/crates/tish_core/src/lib.rs +17 -0
  72. package/crates/tish_core/src/macros.rs +36 -0
  73. package/crates/tish_core/src/uri.rs +118 -0
  74. package/crates/tish_core/src/value.rs +696 -0
  75. package/crates/tish_core/src/vmref.rs +178 -0
  76. package/crates/tish_cranelift/Cargo.toml +19 -0
  77. package/crates/tish_cranelift/src/lib.rs +43 -0
  78. package/crates/tish_cranelift/src/link.rs +117 -0
  79. package/crates/tish_cranelift/src/lower.rs +85 -0
  80. package/crates/tish_cranelift_runtime/Cargo.toml +25 -0
  81. package/crates/tish_cranelift_runtime/src/lib.rs +45 -0
  82. package/crates/tish_eval/Cargo.toml +45 -0
  83. package/crates/tish_eval/src/eval.rs +3717 -0
  84. package/crates/tish_eval/src/http.rs +188 -0
  85. package/crates/tish_eval/src/lib.rs +99 -0
  86. package/crates/tish_eval/src/natives.rs +399 -0
  87. package/crates/tish_eval/src/promise.rs +179 -0
  88. package/crates/tish_eval/src/regex.rs +299 -0
  89. package/crates/tish_eval/src/timers.rs +120 -0
  90. package/crates/tish_eval/src/value.rs +318 -0
  91. package/crates/tish_eval/src/value_convert.rs +111 -0
  92. package/crates/tish_fmt/Cargo.toml +16 -0
  93. package/crates/tish_fmt/src/bin/tish-fmt.rs +41 -0
  94. package/crates/tish_fmt/src/lib.rs +2101 -0
  95. package/crates/tish_jsx_web/Cargo.toml +9 -0
  96. package/crates/tish_jsx_web/README.md +5 -0
  97. package/crates/tish_jsx_web/src/lib.rs +2 -0
  98. package/crates/tish_lexer/Cargo.toml +9 -0
  99. package/crates/tish_lexer/src/lib.rs +716 -0
  100. package/crates/tish_lexer/src/token.rs +163 -0
  101. package/crates/tish_lint/Cargo.toml +18 -0
  102. package/crates/tish_lint/src/bin/tish-lint.rs +195 -0
  103. package/crates/tish_lint/src/lib.rs +289 -0
  104. package/crates/tish_llvm/Cargo.toml +13 -0
  105. package/crates/tish_llvm/src/lib.rs +115 -0
  106. package/crates/tish_lsp/Cargo.toml +25 -0
  107. package/crates/tish_lsp/README.md +26 -0
  108. package/crates/tish_lsp/src/builtin_goto.rs +362 -0
  109. package/crates/tish_lsp/src/import_goto.rs +562 -0
  110. package/crates/tish_lsp/src/main.rs +1046 -0
  111. package/crates/tish_native/Cargo.toml +16 -0
  112. package/crates/tish_native/src/build.rs +427 -0
  113. package/crates/tish_native/src/config.rs +48 -0
  114. package/crates/tish_native/src/lib.rs +416 -0
  115. package/crates/tish_opt/Cargo.toml +13 -0
  116. package/crates/tish_opt/src/lib.rs +943 -0
  117. package/crates/tish_parser/Cargo.toml +11 -0
  118. package/crates/tish_parser/src/lib.rs +332 -0
  119. package/crates/tish_parser/src/parser.rs +2304 -0
  120. package/crates/tish_pg/Cargo.toml +34 -0
  121. package/crates/tish_pg/README.md +38 -0
  122. package/crates/tish_pg/src/error.rs +52 -0
  123. package/crates/tish_pg/src/lib.rs +955 -0
  124. package/crates/tish_resolve/Cargo.toml +13 -0
  125. package/crates/tish_resolve/src/lib.rs +3561 -0
  126. package/crates/tish_resolve/src/pos.rs +141 -0
  127. package/crates/tish_runtime/Cargo.toml +96 -0
  128. package/crates/tish_runtime/src/http.rs +1298 -0
  129. package/crates/tish_runtime/src/http_fetch.rs +471 -0
  130. package/crates/tish_runtime/src/http_hyper.rs +418 -0
  131. package/crates/tish_runtime/src/http_prefork.rs +189 -0
  132. package/crates/tish_runtime/src/lib.rs +1192 -0
  133. package/crates/tish_runtime/src/native_promise.rs +15 -0
  134. package/crates/tish_runtime/src/promise.rs +248 -0
  135. package/crates/tish_runtime/src/promise_io.rs +38 -0
  136. package/crates/tish_runtime/src/timers.rs +166 -0
  137. package/crates/tish_runtime/src/ws.rs +761 -0
  138. package/crates/tish_runtime/tests/fetch_readable_stream.rs +102 -0
  139. package/crates/tish_ui/Cargo.toml +17 -0
  140. package/crates/tish_ui/src/jsx.rs +682 -0
  141. package/crates/tish_ui/src/lib.rs +20 -0
  142. package/crates/tish_ui/src/runtime/hooks.rs +569 -0
  143. package/crates/tish_ui/src/runtime/mod.rs +180 -0
  144. package/crates/tish_vm/Cargo.toml +47 -0
  145. package/crates/tish_vm/src/lib.rs +39 -0
  146. package/crates/tish_vm/src/vm.rs +2192 -0
  147. package/crates/tish_vm/tests/fixtures/or_string_cmd.tish +2 -0
  148. package/crates/tish_vm/tests/lexical_scope_declare.rs +34 -0
  149. package/crates/tish_vm/tests/peephole_jump_chain_logical_or.rs +150 -0
  150. package/crates/tish_wasm/Cargo.toml +15 -0
  151. package/crates/tish_wasm/src/lib.rs +424 -0
  152. package/crates/tish_wasm_runtime/Cargo.toml +37 -0
  153. package/crates/tish_wasm_runtime/src/gpu.rs +413 -0
  154. package/crates/tish_wasm_runtime/src/lib.rs +42 -0
  155. package/crates/tishlang_cargo_bindgen/Cargo.toml +26 -0
  156. package/crates/tishlang_cargo_bindgen/src/classify.rs +263 -0
  157. package/crates/tishlang_cargo_bindgen/src/discover.rs +125 -0
  158. package/crates/tishlang_cargo_bindgen/src/infer.rs +382 -0
  159. package/crates/tishlang_cargo_bindgen/src/lib.rs +349 -0
  160. package/crates/tishlang_cargo_bindgen/src/main.rs +167 -0
  161. package/crates/tishlang_cargo_bindgen/src/metadata.rs +117 -0
  162. package/justfile +268 -0
  163. package/package.json +1 -1
  164. package/platform/darwin-arm64/tish-fmt +0 -0
@@ -0,0 +1,11 @@
1
+ [package]
2
+ name = "tishlang_parser"
3
+ version = "0.1.0"
4
+ edition = "2021"
5
+ description = "Tish recursive descent parser"
6
+
7
+ license-file = { workspace = true }
8
+ repository = { workspace = true }
9
+ [dependencies]
10
+ tishlang_lexer = { path = "../tish_lexer", version = ">=0.1" }
11
+ tishlang_ast = { path = "../tish_ast", version = ">=0.1" }
@@ -0,0 +1,332 @@
1
+ //! Tish recursive descent parser.
2
+
3
+ mod parser;
4
+
5
+ use parser::Parser;
6
+
7
+ use tishlang_ast::Program;
8
+ use tishlang_lexer::Lexer;
9
+
10
+ pub fn parse(source: &str) -> Result<Program, String> {
11
+ let lexer = Lexer::new(source);
12
+ let tokens: Result<Vec<_>, _> = lexer.collect();
13
+ let tokens = tokens?;
14
+ let mut parser = Parser::new(&tokens);
15
+ parser.parse_program()
16
+ }
17
+
18
+ #[cfg(test)]
19
+ mod tests {
20
+ use super::*;
21
+ use tishlang_ast::{CallArg, Expr, ObjectProp, Statement};
22
+
23
+ #[test]
24
+ fn test_async_fn_parse() {
25
+ let program = parse("async fn foo() { }").expect("parse async fn");
26
+ assert_eq!(program.statements.len(), 1);
27
+ if let tishlang_ast::Statement::FunDecl { async_, name, .. } = &program.statements[0] {
28
+ assert!(async_, "expected async function");
29
+ assert_eq!(name.as_ref(), "foo");
30
+ } else {
31
+ panic!("expected FunDecl");
32
+ }
33
+ }
34
+
35
+ #[test]
36
+ fn test_object_literal_shorthand_single() {
37
+ let program = parse("const o = { port }").expect("parse object shorthand");
38
+ assert_eq!(program.statements.len(), 1);
39
+ let stmt = &program.statements[0];
40
+ let init = match stmt {
41
+ Statement::VarDecl {
42
+ init: Some(ref i), ..
43
+ } => i,
44
+ _ => panic!("expected VarDecl with init"),
45
+ };
46
+ let props = match init {
47
+ Expr::Object { ref props, .. } => props,
48
+ _ => panic!("expected Object expr"),
49
+ };
50
+ assert_eq!(props.len(), 1);
51
+ match &props[0] {
52
+ ObjectProp::KeyValue(k, v) => {
53
+ assert_eq!(k.as_ref(), "port");
54
+ if let Expr::Ident { ref name, .. } = v {
55
+ assert_eq!(name.as_ref(), "port");
56
+ } else {
57
+ panic!("expected Ident value for shorthand");
58
+ }
59
+ }
60
+ _ => panic!("expected KeyValue prop"),
61
+ }
62
+ }
63
+
64
+ #[test]
65
+ fn test_object_literal_string_key() {
66
+ let program =
67
+ parse(r#"const o = { "ai-a": 0, human: 1 }"#).expect("parse object with string key");
68
+ assert_eq!(program.statements.len(), 1);
69
+ let stmt = &program.statements[0];
70
+ let init = match stmt {
71
+ Statement::VarDecl {
72
+ init: Some(ref i), ..
73
+ } => i,
74
+ _ => panic!("expected VarDecl with init"),
75
+ };
76
+ let props = match init {
77
+ Expr::Object { ref props, .. } => props,
78
+ _ => panic!("expected Object expr"),
79
+ };
80
+ assert_eq!(props.len(), 2);
81
+ match &props[0] {
82
+ ObjectProp::KeyValue(k, _) => assert_eq!(k.as_ref(), "ai-a"),
83
+ _ => panic!("expected KeyValue prop"),
84
+ }
85
+ match &props[1] {
86
+ ObjectProp::KeyValue(k, _) => assert_eq!(k.as_ref(), "human"),
87
+ _ => panic!("expected KeyValue prop"),
88
+ }
89
+ }
90
+
91
+ #[test]
92
+ fn test_object_literal_shorthand_mixed() {
93
+ let program = parse("const o = { port, x: 1 }").expect("parse mixed object");
94
+ assert_eq!(program.statements.len(), 1);
95
+ let stmt = &program.statements[0];
96
+ let init = match stmt {
97
+ Statement::VarDecl {
98
+ init: Some(ref i), ..
99
+ } => i,
100
+ _ => panic!("expected VarDecl with init"),
101
+ };
102
+ let props = match init {
103
+ Expr::Object { ref props, .. } => props,
104
+ _ => panic!("expected Object expr"),
105
+ };
106
+ assert_eq!(props.len(), 2);
107
+ match &props[0] {
108
+ ObjectProp::KeyValue(k, v) => {
109
+ assert_eq!(k.as_ref(), "port");
110
+ if let Expr::Ident { ref name, .. } = v {
111
+ assert_eq!(name.as_ref(), "port");
112
+ } else {
113
+ panic!("expected Ident value for shorthand");
114
+ }
115
+ }
116
+ _ => panic!("expected KeyValue prop"),
117
+ }
118
+ match &props[1] {
119
+ ObjectProp::KeyValue(k, v) => {
120
+ assert_eq!(k.as_ref(), "x");
121
+ if let Expr::Literal { .. } = v {
122
+ // x: 1
123
+ } else {
124
+ panic!("expected Literal for x");
125
+ }
126
+ }
127
+ _ => panic!("expected KeyValue prop"),
128
+ }
129
+ }
130
+
131
+ fn unwrap_expr_stmt(program: &tishlang_ast::Program) -> &Expr {
132
+ match program.statements.first() {
133
+ Some(Statement::ExprStmt { expr, .. }) => expr,
134
+ _ => panic!("expected expression statement"),
135
+ }
136
+ }
137
+
138
+ #[test]
139
+ fn new_expression_simple_call() {
140
+ let program = parse("new Foo()").expect("parse");
141
+ let e = unwrap_expr_stmt(&program);
142
+ match e {
143
+ Expr::New { callee, args, .. } => {
144
+ assert!(
145
+ matches!(callee.as_ref(), Expr::Ident { name, .. } if name.as_ref() == "Foo")
146
+ );
147
+ assert!(args.is_empty());
148
+ }
149
+ _ => panic!("expected New, got {:?}", e),
150
+ }
151
+ }
152
+
153
+ #[test]
154
+ fn new_expression_with_args() {
155
+ let program = parse("new Uint8Array(16)").expect("parse");
156
+ let e = unwrap_expr_stmt(&program);
157
+ match e {
158
+ Expr::New { callee, args, .. } => {
159
+ assert!(
160
+ matches!(callee.as_ref(), Expr::Ident { name, .. } if name.as_ref() == "Uint8Array")
161
+ );
162
+ assert_eq!(args.len(), 1);
163
+ assert!(matches!(&args[0], CallArg::Expr(Expr::Literal { .. })));
164
+ }
165
+ _ => panic!("expected New"),
166
+ }
167
+ }
168
+
169
+ #[test]
170
+ fn new_expression_member_callee() {
171
+ let program = parse("new ns.AudioContext()").expect("parse");
172
+ let e = unwrap_expr_stmt(&program);
173
+ match e {
174
+ Expr::New { callee, args, .. } => {
175
+ assert!(matches!(
176
+ callee.as_ref(),
177
+ Expr::Member { prop: tishlang_ast::MemberProp::Name { name, .. }, .. } if name.as_ref() == "AudioContext"
178
+ ));
179
+ assert!(args.is_empty());
180
+ }
181
+ _ => panic!("expected New"),
182
+ }
183
+ }
184
+
185
+ #[test]
186
+ fn new_expression_chained_new() {
187
+ let program = parse("new new Date()").expect("parse");
188
+ let e = unwrap_expr_stmt(&program);
189
+ match e {
190
+ Expr::New { callee, args, .. } => {
191
+ assert!(args.is_empty());
192
+ match callee.as_ref() {
193
+ Expr::New {
194
+ callee: inner,
195
+ args: inner_args,
196
+ ..
197
+ } => {
198
+ assert!(
199
+ matches!(inner.as_ref(), Expr::Ident { name, .. } if name.as_ref() == "Date")
200
+ );
201
+ assert!(inner_args.is_empty());
202
+ }
203
+ _ => panic!("expected nested New"),
204
+ }
205
+ }
206
+ _ => panic!("expected New"),
207
+ }
208
+ }
209
+
210
+ #[test]
211
+ fn new_then_member_access() {
212
+ let program = parse("new Foo().bar").expect("parse");
213
+ let e = unwrap_expr_stmt(&program);
214
+ match e {
215
+ Expr::Member {
216
+ object,
217
+ prop: tishlang_ast::MemberProp::Name { name, .. },
218
+ ..
219
+ } => {
220
+ assert_eq!(name.as_ref(), "bar");
221
+ match object.as_ref() {
222
+ Expr::New { callee, args, .. } => {
223
+ assert!(
224
+ matches!(callee.as_ref(), Expr::Ident { name, .. } if name.as_ref() == "Foo")
225
+ );
226
+ assert!(args.is_empty());
227
+ }
228
+ _ => panic!("expected New object"),
229
+ }
230
+ }
231
+ _ => panic!("expected Member"),
232
+ }
233
+ }
234
+
235
+ #[test]
236
+ fn new_with_spread_arg() {
237
+ let program = parse("new Foo(...xs)").expect("parse");
238
+ let e = unwrap_expr_stmt(&program);
239
+ match e {
240
+ Expr::New { args, .. } => {
241
+ assert!(
242
+ matches!(&args[0], CallArg::Spread(Expr::Ident { name, .. }) if name.as_ref() == "xs")
243
+ );
244
+ }
245
+ _ => panic!("expected New"),
246
+ }
247
+ }
248
+
249
+ #[test]
250
+ fn stdlib_builtins_d_tish_parses() {
251
+ const SRC: &str = include_str!("../../../stdlib/builtins.d.tish");
252
+ parse(SRC).expect("stdlib/builtins.d.tish should parse");
253
+ }
254
+
255
+ #[test]
256
+ fn for_empty_head_parses() {
257
+ let src = r#"fn f() {
258
+ for (;;)
259
+ const x = 1
260
+ }"#;
261
+ let program = parse(src).expect("for (;;)");
262
+ let body = match &program.statements[0] {
263
+ Statement::FunDecl { body, .. } => body,
264
+ _ => panic!("expected fn"),
265
+ };
266
+ let stmts = match body.as_ref() {
267
+ Statement::Block { statements, .. } => statements,
268
+ _ => panic!("expected block body"),
269
+ };
270
+ assert!(
271
+ matches!(
272
+ stmts.iter().find(|s| matches!(s, Statement::For { .. })),
273
+ Some(Statement::For {
274
+ init: None,
275
+ cond: None,
276
+ update: None,
277
+ ..
278
+ })
279
+ ),
280
+ "expected for (;;)"
281
+ );
282
+ }
283
+
284
+ #[test]
285
+ fn brace_function_body_does_not_nest_block_around_first_let() {
286
+ let src = "fn h() {\n let a = 1\n let b = 2\n}\n";
287
+ let program = parse(src).expect("parse");
288
+ let body = match &program.statements[0] {
289
+ Statement::FunDecl { body, .. } => body,
290
+ _ => panic!("expected fn"),
291
+ };
292
+ let stmts = match body.as_ref() {
293
+ Statement::Block { statements, .. } => statements,
294
+ _ => panic!("expected block body"),
295
+ };
296
+ assert_eq!(
297
+ stmts.len(),
298
+ 2,
299
+ "expected two top-level lets in fn body, not Block(let) + let — got {stmts:?}"
300
+ );
301
+ assert!(matches!(stmts[0], Statement::VarDecl { .. }));
302
+ assert!(matches!(stmts[1], Statement::VarDecl { .. }));
303
+ }
304
+
305
+ #[test]
306
+ fn member_access_allows_type_property_name() {
307
+ let src = "fn f() {\n const label = 0\n label.type = \"button\"\n}\n";
308
+ parse(src).expect("label.type should parse: `type` is a keyword but valid after `.`");
309
+ }
310
+
311
+ #[test]
312
+ fn brace_block_stmt_then_const_then_if_are_siblings() {
313
+ let src = "fn g() {\n f()\n const x = 1\n if (x) {\n f()\n }\n}\n";
314
+ let program = parse(src).expect("parse");
315
+ let body = match &program.statements[0] {
316
+ Statement::FunDecl { body, .. } => body,
317
+ _ => panic!("expected fn"),
318
+ };
319
+ let stmts = match body.as_ref() {
320
+ Statement::Block { statements, .. } => statements,
321
+ _ => panic!("expected block body"),
322
+ };
323
+ assert_eq!(
324
+ stmts.len(),
325
+ 3,
326
+ "expected expr; const; if as siblings — got {stmts:?}"
327
+ );
328
+ assert!(matches!(stmts[0], Statement::ExprStmt { .. }));
329
+ assert!(matches!(stmts[1], Statement::VarDecl { .. }));
330
+ assert!(matches!(stmts[2], Statement::If { .. }));
331
+ }
332
+ }