1 | Yaks Syntax
|
2 | ===========
|
3 |
|
4 | ## CST-Like IR
|
5 |
|
6 | (class ParseHay vm._Callable # we have limited infix . for readability
|
7 | # WASM also has this?
|
8 | (var fd_state process.FdState)
|
9 | (var parse_ctx parse_lib.ParseContext)
|
10 |
|
11 | (func _init [this.fd_state, this.parse_ctx, this.errfmt]
|
12 | )
|
13 |
|
14 | (func _Call [path Str] value_t
|
15 | (var call_loc loc.Missing)
|
16 |
|
17 | # https://stackoverflow.com/questions/16493079/how-to-implement-a-try-catch-block-in-scheme
|
18 |
|
19 | (try # extra level of indent is annoying
|
20 | (var f (this.fd_state.Open path))
|
21 | (except [IOError_OSError] [e]
|
22 | (var msg (posix.sterror e.errno))
|
23 | (throw error.Expr (fmt "Couldn't open "%r: %s" path msg) call_loc))
|
24 | (except ...
|
25 | )
|
26 | )
|
27 | )
|
28 | )
|
29 |
|
30 | (class ctx_Try []
|
31 | (var mutable_opts MutableOpts)
|
32 |
|
33 | (func _init [this.fd_state, this.parse_ctx, this.errfmt]
|
34 | (mutableOpts.Push option_i.errexit True)
|
35 | )
|
36 | (func _destroy []
|
37 | (this.mutable_ops.Pop option_i.errexit)
|
38 | )
|
39 | )
|
40 |
|
41 | OK this is actually not bad. And it saves us from reusing YSH syntax. Hm.
|
42 | think we just need the infix dot sugar in the reader?
|
43 |
|
44 | Note that the bootstrap compiler won't have `class try with`.
|
45 |
|
46 | - It will only have `func data enum`, `global var setvar`, `for while`, `if switch`.
|
47 | - Globals are always constants, and incur no startup time.
|
48 |
|
49 | ## Abandoned YSH-like syntax -- too much work
|
50 |
|
51 | Example of better syntax which we already support:
|
52 |
|
53 | func f(a List[Int], b Dict[Str, Int]) {
|
54 | case (node->tag()) {
|
55 | (command_e.Simple) {
|
56 | }
|
57 | (command_e.ShAssignment) {
|
58 | }
|
59 | }
|
60 |
|
61 | # We would need to add something like this?
|
62 | with (dev.ctx_Tracer(this.tracer, 'source', cmd_val.argv)) {
|
63 | var source_argv = arg_r.Rest() # C++ needs type inference here?
|
64 | }
|
65 | return (x)
|
66 | }
|
67 |
|
68 | Example of class support:
|
69 |
|
70 | class ParseHay : vm._Callable {
|
71 | var fd_state: process.FdState
|
72 | var parse_ctx: parse_lib.ParseContext
|
73 | var errfmt: ui.ErrorFormatter
|
74 |
|
75 | # auto-assign members, infer types
|
76 | func init(this.fd_state, this.parse_ctx, this.errfmt) {
|
77 | }
|
78 |
|
79 | func _Call(path Str) -> value_t {
|
80 | var call_loc = loc.Missing
|
81 | try {
|
82 | var f = this.fd_state.Open(path)
|
83 | } except (IOError, OSError) as e { # can paper over IOError
|
84 | var msg = posix.strerror(e.errno)
|
85 | throw error.Expr("Couldn't open %r: %s" % (path, msg), call_loc)
|
86 | }
|
87 | }
|
88 | }
|
89 |
|
90 | class ctx_Try {
|
91 | var mutable_opts: MutableOpts
|
92 |
|
93 | # would we have 'fn' that gets rid of :: ? Perhaps
|
94 | func _init(this.mutable_opts) {
|
95 | :: mutable_opts.Push(option_i.errexit, true)
|
96 | }
|
97 |
|
98 | func _destroy() {
|
99 | this.mutable_opts.Pop(option_i.errexit)
|
100 | }
|
101 | }
|
102 |
|
103 | - static stuff which I added in ysh/grammar.pgen2, now yaks/old/tea.pgen2
|
104 | - virtual override abstract - this isn't horrible
|
105 |
|
106 | Problem: this would break INTERPRETER flow, unless you generate Python! which
|
107 | is possible, though possibly ugly.
|
108 |
|
109 | This is another reason not to use it.
|
110 |
|