forked from cppvik/teleperl
-
Notifications
You must be signed in to change notification settings - Fork 0
/
tl.yp
112 lines (87 loc) · 2.34 KB
/
tl.yp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
%{
use constant {
TL_TYPES => 0,
TL_FUNCS => 1,
};
our $tl_context = TL_TYPES;
%}
%token NUM
%token LC_ID
%token UC_ID
%token ID_HASH
%token FUNCTIONS TYPES
%start program
%left '.'
%%
type_term: type_id { { name => $_[1] } }
| '!' type_id { { name => $_[2], bang => 1 } }
| type_id '<' tpar_list '>' { { name => $_[1], t_args => $_[3], template => 1 } }
;
tpar_list: type_id { [ $_[1] ] }
| tpar_list ',' type_id { [ @$_[1], $_[3] ] }
;
type_id: full_id | '#' { "nat"; } ;
full_id: LC_ID
| LC_ID '.' LC_ID { $_[1] .".". $_[3] }
| UC_ID
| LC_ID '.' UC_ID { $_[1] .".". $_[3] }
;
program: declarations
{
print "Whole schema parsed\n";
}
;
declarations: /* empty */
| declarations declaration
;
declaration: combinator
| functions_separator
| types_separator
;
functions_separator: FUNCTIONS
{
$tl_context = TL_FUNCS;
print "functions!\n";
}
;
types_separator: TYPES
{
$tl_context = TL_TYPES;
print "types!\n";
}
;
combinator: full_id opt_hash opt_args args '=' result_type ';'
{
if ($tl_context == TL_TYPES) {
push @{$_[0]->YYData->{types}}, { id => $_[1], hash => $_[2], type => $_[6], args => $_[4] };
}
else {
push @{$_[0]->YYData->{funcs}}, { id => $_[1], hash => $_[2], type => $_[6], args => $_[4] };
}
}
;
opt_hash: /* empty */ { 0; }
| ID_HASH
;
opt_args: /* empty */
| '{' args '}'
;
args: /* empty */ { [] }
| args arg { push @{$_[1]}, $_[2]; $_[1] }
;
arg: LC_ID ':' type_term { { name => $_[1], type => $_[3] } }
| LC_ID ':' condition '?' type_term { { name => $_[1], cond => $_[3], type => $_[5] } }
| UC_ID ':' type_term { { name => $_[1], type => $_[3] } }
| type_term { { type => $_[1] } }
| '[' LC_ID ']' { { type => $_[2], mult => 1 } }
;
condition: LC_ID bit_selector { { name => $_[1], bitmask => $_[2] } }
;
bit_selector: /* empty */ { -1; }
| '.' NUM { 1 << $_[2]; }
;
result_type: type_term opt_params;
opt_params: /* empty */
| opt_params LC_ID
;
%%