1
1
"""Parser for bytecodes.inst."""
2
2
3
3
from dataclasses import dataclass , field
4
- from typing import NamedTuple , Callable , TypeVar
4
+ from typing import NamedTuple , Callable , TypeVar , Literal
5
5
6
6
import lexer as lx
7
7
from plexer import PLexer
@@ -74,16 +74,22 @@ class CacheEffect(Node):
74
74
75
75
@dataclass
76
76
class InstHeader (Node ):
77
+ kind : Literal ["inst" , "op" ]
77
78
name : str
78
79
inputs : list [InputEffect ]
79
80
outputs : list [OutputEffect ]
80
81
81
82
82
83
@dataclass
83
84
class InstDef (Node ):
85
+ # TODO: Merge InstHeader and InstDef
84
86
header : InstHeader
85
87
block : Block
86
88
89
+ @property
90
+ def kind (self ) -> str :
91
+ return self .header .kind
92
+
87
93
@property
88
94
def name (self ) -> str :
89
95
return self .header .name
@@ -99,6 +105,7 @@ def outputs(self) -> list[StackEffect]:
99
105
100
106
@dataclass
101
107
class Super (Node ):
108
+ kind : Literal ["macro" , "super" ]
102
109
name : str
103
110
ops : list [str ]
104
111
@@ -122,10 +129,12 @@ def inst_def(self) -> InstDef | None:
122
129
123
130
@contextual
124
131
def inst_header (self ) -> InstHeader | None :
125
- # inst(NAME) | inst(NAME, (inputs -- outputs))
132
+ # inst(NAME)
133
+ # | inst(NAME, (inputs -- outputs))
134
+ # | op(NAME, (inputs -- outputs))
126
135
# TODO: Error out when there is something unexpected.
127
136
# TODO: Make INST a keyword in the lexer.
128
- if (tkn := self .expect (lx .IDENTIFIER )) and tkn .text == "inst" :
137
+ if (tkn := self .expect (lx .IDENTIFIER )) and ( kind := tkn .text ) in ( "inst" , "op" ) :
129
138
if (self .expect (lx .LPAREN )
130
139
and (tkn := self .expect (lx .IDENTIFIER ))):
131
140
name = tkn .text
@@ -134,9 +143,10 @@ def inst_header(self) -> InstHeader | None:
134
143
if self .expect (lx .RPAREN ):
135
144
if ((tkn := self .peek ())
136
145
and tkn .kind == lx .LBRACE ):
137
- return InstHeader (name , inp , outp )
138
- elif self .expect (lx .RPAREN ):
139
- return InstHeader (name , [], [])
146
+ return InstHeader (kind , name , inp , outp )
147
+ elif self .expect (lx .RPAREN ) and kind == "inst" :
148
+ # No legacy stack effect if kind is "op".
149
+ return InstHeader (kind , name , [], [])
140
150
return None
141
151
142
152
def stack_effect (self ) -> tuple [list [InputEffect ], list [OutputEffect ]]:
@@ -200,13 +210,13 @@ def output(self) -> OutputEffect | None:
200
210
201
211
@contextual
202
212
def super_def (self ) -> Super | None :
203
- if (tkn := self .expect (lx .IDENTIFIER )) and tkn .text == "super" :
213
+ if (tkn := self .expect (lx .IDENTIFIER )) and ( kind := tkn .text ) in ( "super" , "macro" ) :
204
214
if self .expect (lx .LPAREN ):
205
215
if (tkn := self .expect (lx .IDENTIFIER )):
206
216
if self .expect (lx .RPAREN ):
207
217
if self .expect (lx .EQUALS ):
208
218
if ops := self .ops ():
209
- res = Super (tkn .text , ops )
219
+ res = Super (kind , tkn .text , ops )
210
220
return res
211
221
212
222
def ops (self ) -> list [str ] | None :
@@ -278,7 +288,7 @@ def c_blob(self) -> list[lx.Token]:
278
288
filename = sys .argv [1 ]
279
289
if filename == "-c" and sys .argv [2 :]:
280
290
src = sys .argv [2 ]
281
- filename = None
291
+ filename = "<string>"
282
292
else :
283
293
with open (filename ) as f :
284
294
src = f .read ()
@@ -287,7 +297,7 @@ def c_blob(self) -> list[lx.Token]:
287
297
end = srclines .index ("// END BYTECODES //" )
288
298
src = "\n " .join (srclines [begin + 1 : end ])
289
299
else :
290
- filename = None
300
+ filename = "<default>"
291
301
src = "if (x) { x.foo; // comment\n }"
292
302
parser = Parser (src , filename )
293
303
x = parser .inst_def () or parser .super_def () or parser .family_def ()
0 commit comments