OILS / yaks / old / tea.pgen2 View on Github | oilshell.org

137 lines, 48 significant
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
13tea_word: (
14 dq_string | sq_string
15 | sh_command_sub | braced_var_sub | simple_var_sub
16)
17
18type_expr_list: type_expr (',' type_expr)*
19
20# Note: It may make sense to have ; here, for named params only!
21data_params: (param ',')* [ param [','] ]
22
23# zero params allowed for consistency with func and class?
24tea_data: Expr_Name '(' [data_params] ')'
25
26# e.g. Nullary %Token or Nullary(x Int)
27variant_type: Expr_Symbol | '(' data_params ')'
28variant: 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
37tea_enum: (
38 Expr_Name '{' [Op_Newline]
39 # note: braces can be empty
40 [ variant (comma_newline variant)* [comma_newline] ]
41 '}'
42)
43
44suite: '{' [Op_Newline] [func_items] '}'
45
46func_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 }
70func_items: func_item (semi_newline func_item)* [semi_newline]
71
72# This is anonymous
73tea_func: (
74 '(' [param_group] [';' param_group] ')' [type_expr_list]
75 suite
76)
77named_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
93class_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 }
101class_items: class_item (semi_newline class_item)* [semi_newline]
102
103tea_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.
107end_import: ';' | Op_Newline
108
109import_name: Expr_Name ['as' Expr_Name]
110import_names: import_name (comma_newline import_name)* [import_name]
111
112# TODO: Should we have a simpler YSH string literal?
113tea_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
120end_outer: ';' [Op_Newline] | Op_Newline | Eof_Real
121
122module_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
136tea_module: [Op_Newline] module_item* [Eof_Real]
137