1515 RightFieldAccess ,
1616 RightCompare ,
1717 RightIndex ,
18+ RightOptional ,
1819};
1920
2021typedef struct {
@@ -28,6 +29,7 @@ RightOperator right_operator_table[128] = {
2829 [TokenDoublePlus ] = { 1 , RightIncDec }, [TokenDoubleMinus ] = { 1 , RightIncDec },
2930 ['[' ] = { 1 , RightIndex }, ['(' ] = { 1 , RightCall },
3031 ['.' ] = { 1 , RightFieldAccess }, [TokenRightArrow ] = { 1 , RightFieldAccess },
32+ ['?' ] = { 1 , RightOptional },
3133
3234 ['*' ] = { 3 , RightAltBinary }, ['/' ] = { 3 }, ['%' ] = { 3 },
3335
@@ -171,6 +173,18 @@ Message see_declaration(Declaration* declaration, Node* node) {
171173 (int ) node -> trace .slice .size , node -> trace .slice .data ));
172174}
173175
176+ Node * temp_value (Node * value , Parser * parser , unsigned * set_id ) {
177+ static unsigned id = 0 ;
178+ if (set_id ) * set_id = id ;
179+ const str declaration_code = strf (0 , "auto __qv%u = extern<auto> \"\";%c" , id ++ , '\0' );
180+ Node * declaration = eval_w (parser -> tokenizer -> current .trace .filename ,
181+ declaration_code .data , parser , & statement );
182+ declaration -> Statement .expression -> BinaryOperation .right = value ;
183+ clash_types (declaration -> Statement .expression -> BinaryOperation .left -> type ,
184+ value -> type , value -> trace , parser -> tokenizer -> messages , 0 );
185+ return declaration ;
186+ }
187+
174188Node * right (Node * lefthand , Parser * parser , unsigned char precedence ) {
175189 RightOperator operator ;
176190outer_while :
@@ -179,6 +193,78 @@ Node* right(Node* lefthand, Parser* parser, unsigned char precedence) {
179193 if (operator .precedence == 6 && collecting_type_arguments ) break ;
180194
181195 switch (operator .type ) {
196+ case RightOptional : {
197+ Trace trace_end = next (parser -> tokenizer ).trace ;
198+
199+ if ((operator = right_operator_table [parser -> tokenizer -> current .type ])
200+ .precedence <= 1 ) {
201+ unsigned temp_id ;
202+ Node * temp = temp_value (lefthand , parser , & temp_id );
203+
204+ const str left_value_code = strf (0 , "__qv%u.value%c" , temp_id , '\0' );
205+ Node * some_branch = right (eval (NULL , left_value_code .data , parser ),
206+ parser , 2 );
207+
208+ Scope * collection = new_scope (NULL );
209+ collection -> trace = lefthand -> trace ;
210+ collection -> wrap_brackets = 1 ;
211+ push (& collection -> children , temp );
212+
213+ const OpenedType open = open_type (some_branch -> type , 0 );
214+ if (open .type -> compiler == (void * ) comp_External &&
215+ streq (open .type -> External .data , str ("void" ))) {
216+ Node * if_statement = eval_w (NULL , strf (0 ,
217+ "if(__qv%u.some) extern<auto> _;%c" , temp_id , '\0' ).data ,
218+ parser , & statement );
219+ if_statement -> Control .body -> children .data [0 ]-> Statement .expression
220+ = some_branch ;
221+ push (& collection -> children , if_statement );
222+ close_type (open .actions , 0 );
223+ return (void * ) collection ;
224+ }
225+ close_type (open .actions , 0 );
226+
227+ unsigned value_id ;
228+ Node * value = temp_value (eval (NULL , "Option::None()" , parser ),
229+ parser , & value_id );
230+
231+ const str if_statement_code = strf (0 ,
232+ "if(__qv%u.some) __qv%u = Option::Some(extern<auto> _);%c" ,
233+ temp_id , value_id , '\0' );
234+ Node * if_statement = eval_w (NULL , if_statement_code .data , parser ,
235+ & statement );
236+ printf ("%p %p\n" ,
237+ if_statement -> Control .body -> children .data [0 ]-> compiler ,
238+ comp_Statement );
239+ // exit(1);
240+ clash_types (if_statement -> Control .body -> children .data [0 ]-> Statement
241+ .expression -> BinaryOperation .right -> FunctionCall .arguments
242+ .data [0 ]-> type , some_branch -> type , some_branch -> trace ,
243+ parser -> tokenizer -> messages , 0 );
244+ if_statement -> Control .body -> children .data [0 ]-> Statement .expression
245+ -> BinaryOperation .right -> FunctionCall .arguments .data [0 ] = some_branch ;
246+
247+ push (& collection -> children , value );
248+ push (& collection -> children , if_statement );
249+ collection -> value = eval (NULL , strf (0 , "__qv%u%c" , value_id , 0 ).data ,
250+ parser );
251+ collection -> type = collection -> value -> type ;
252+
253+ lefthand = (void * ) collection ;
254+ break ;
255+ }
256+
257+ if (lefthand -> flags & fType ) {
258+ Wrapper * option = (void * ) eval ("option" , "Option" , parser );
259+ clash_types (option -> action .TypeList .data [0 ], (void * ) lefthand ,
260+ stretch (lefthand -> trace , trace_end ),
261+ parser -> tokenizer -> messages , 0 );
262+ lefthand = (void * ) option ;
263+ break ;
264+ }
265+ break ;
266+ }
267+
182268 case RightIncDec : {
183269 if (!(lefthand -> flags & fMutable ) || lefthand -> type -> flags & fConst ) {
184270 push (parser -> tokenizer -> messages , Err ( lefthand -> trace ,
@@ -187,13 +273,14 @@ Node* right(Node* lefthand, Parser* parser, unsigned char precedence) {
187273
188274 Trace operator = next (parser -> tokenizer ).trace ;
189275
190- return new_node ((Node ) { .Postfix = {
276+ lefthand = new_node ((Node ) { .Postfix = {
191277 .compiler = (void * ) & comp_Postfix ,
192278 .trace = operator ,
193279 .type = lefthand -> type ,
194280 .child = lefthand ,
195281 .postfix = operator .slice ,
196282 }});
283+ break ;
197284 }
198285
199286 case RightAltBinary : {
@@ -330,7 +417,7 @@ Node* right(Node* lefthand, Parser* parser, unsigned char precedence) {
330417 }});
331418 }
332419
333- case RightFieldAccess : {
420+ case RightFieldAccess : field_access : {
334421 Type * type = lefthand -> type ;
335422 if (parser -> tokenizer -> current .type == TokenRightArrow ) {
336423 type = (void * ) dereference ((void * ) type , lefthand -> trace ,
0 commit comments