1 |
|
2 | # Tea can run a limited form of procs. The first word must be a name, and NO
|
3 | # BARE WORDS.
|
4 | #
|
5 | # Example:
|
6 | # log "hello $name" # valid in OSH, YSH, Tea
|
7 | # myproc $(hostname) # ditto
|
8 | #
|
9 | # my-proc '/' $foo # OSH and YSH
|
10 | # run 'my-proc' '/' $foo # Tea. 'run' is similar to 'command' and 'builtin'
|
11 | #
|
12 |
|
13 | tea_word: (
|
14 | dq_string | sq_string
|
15 | | sh_command_sub | braced_var_sub | simple_var_sub
|
16 | )
|
17 |
|
18 | type_expr_list: type_expr (',' type_expr)*
|
19 |
|
20 | # Note: It may make sense to have ; here, for named params only!
|
21 | data_params: (param ',')* [ param [','] ]
|
22 |
|
23 | # zero params allowed for consistency with func and class?
|
24 | tea_data: Expr_Name '(' [data_params] ')'
|
25 |
|
26 | # e.g. Nullary %Token or Nullary(x Int)
|
27 | variant_type: Expr_Symbol | '(' data_params ')'
|
28 | variant: Expr_Name [ variant_type ]
|
29 |
|
30 | #
|
31 | # Experimental "Tea" stuff
|
32 | #
|
33 | # It also needs:
|
34 | # - cast expressions. Although cast(Int, foo) works I suppose. It feels like
|
35 | # it has a runtime cost
|
36 |
|
37 | tea_enum: (
|
38 | Expr_Name '{' [Op_Newline]
|
39 | # note: braces can be empty
|
40 | [ variant (comma_newline variant)* [comma_newline] ]
|
41 | '}'
|
42 | )
|
43 |
|
44 | suite: '{' [Op_Newline] [func_items] '}'
|
45 |
|
46 | func_item: (
|
47 | ('var' | 'const') name_type_list '=' testlist # ysh_var_decl
|
48 |
|
49 | # TODO: if/switch, with, try/except/throw, etc.
|
50 | | 'while' test suite
|
51 | | 'for' name_type_list 'in' test suite
|
52 |
|
53 | # In Python, imports, assert, etc. also at this 'small_stmt' level
|
54 | | 'break' | 'continue' | 'return' [testlist]
|
55 |
|
56 | # TODO: accept setvar for consistency with YSH?
|
57 | | 'set' place_list (augassign | '=') testlist # ysh_place_mutation
|
58 | # x f(x) etc.
|
59 | #
|
60 | # And x = 1. Python uses the same "hack" to fit within pgen2. It also
|
61 | # supports a = b = 1, which we don't want.
|
62 | #
|
63 | # And echo 'hi' 'there'
|
64 | #
|
65 | # TODO: expr_to_ast needs to validate this
|
66 | | testlist (['=' testlist] | tea_word*)
|
67 | )
|
68 |
|
69 | # we want to avoid requiring newline or ; before }
|
70 | func_items: func_item (semi_newline func_item)* [semi_newline]
|
71 |
|
72 | # This is anonymous
|
73 | tea_func: (
|
74 | '(' [param_group] [';' param_group] ')' [type_expr_list]
|
75 | suite
|
76 | )
|
77 | named_func: Expr_Name tea_func
|
78 |
|
79 | # TODO: Methods differ from functions:
|
80 | # super() can be the first arg
|
81 | # shortcut initializer: Parser(this.lexer) { }
|
82 | # abstract, override, virtual
|
83 | # should we allow annotations, like 'public' or 'export'?
|
84 | #
|
85 | # No field initializers for now. Later C++ versions allow it.
|
86 | #
|
87 | # Annotations:
|
88 | #
|
89 | # func Parse() Int
|
90 | # [override const abstract] {
|
91 | # } ?
|
92 |
|
93 | class_item: (
|
94 | ('virtual' | 'override' | 'func' | 'abstract' ) Expr_Name tea_func
|
95 | # Member declaration
|
96 | | 'var' name_type_list
|
97 | )
|
98 |
|
99 | # Note: we could restrict separators to newlines.
|
100 | # But then you couldn't do class Foo { var a; var b }
|
101 | class_items: class_item (semi_newline class_item)* [semi_newline]
|
102 |
|
103 | tea_class: Expr_Name [':' Expr_Name ] '{' [Op_Newline] [class_items] '}'
|
104 |
|
105 | # 'import' can't use 'semi_newline' because ending with an unknown number of
|
106 | # tokens doesn't compose with our CommandParser.
|
107 | end_import: ';' | Op_Newline
|
108 |
|
109 | import_name: Expr_Name ['as' Expr_Name]
|
110 | import_names: import_name (comma_newline import_name)* [import_name]
|
111 |
|
112 | # TODO: Should we have a simpler YSH string literal?
|
113 | tea_import: sq_string [ 'as' Expr_Name ] ['(' [Op_Newline] [import_names] ')'] end_import
|
114 |
|
115 | # Top level:
|
116 | # declarations of constants -- with const only?
|
117 | # maybe only const?
|
118 | # use, data, enum, class, func. That's it? OK.
|
119 |
|
120 | end_outer: ';' [Op_Newline] | Op_Newline | Eof_Real
|
121 |
|
122 | module_item: (
|
123 | # ysh_var_decl, but no mutation
|
124 | ('var' | 'const') name_type_list '=' testlist end_outer
|
125 | | 'import' tea_import # TODO: needs Eof_Real
|
126 | # Also 'export'
|
127 | | 'class' tea_class end_outer
|
128 | | 'data' tea_data end_outer
|
129 | | 'enum' tea_enum end_outer
|
130 | | 'func' Expr_Name tea_func end_outer
|
131 |
|
132 | # Might need: typedef? Or typealias?
|
133 | )
|
134 |
|
135 | # Eof_Real either after newline or before newline are both valid
|
136 | tea_module: [Op_Newline] module_item* [Eof_Real]
|
137 |
|