1 %{
2 
3 /* Parse ip's macro language.
4  */
5 
6 /*
7 
8     Copyright (C) 1991-2003 The National Gallery
9 
10     This program is free software; you can redistribute it and/or modify
11     it under the terms of the GNU General Public License as published by
12     the Free Software Foundation; either version 2 of the License, or
13     (at your option) any later version.
14 
15     This program is distributed in the hope that it will be useful,
16     but WITHOUT ANY WARRANTY; without even the implied warranty of
17     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18     GNU General Public License for more details.
19 
20     You should have received a copy of the GNU General Public License along
21     with this program; if not, write to the Free Software Foundation, Inc.,
22     51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
23 
24  */
25 
26 /*
27 
28     These files are distributed with VIPS - http://www.vips.ecs.soton.ac.uk
29 
30  */
31 
32 #include "ip.h"
33 
34 /*
35 #define DEBUG
36  */
37 
38 /* trace text read system
39 #define DEBUG_CHARACTER
40  */
41 
42 /* The lexer from lex.l.
43  */
44 int yylex( void );
45 void yyrestart( FILE *input_file );
46 
47 /* Declare file-private stuff, shared with the lexer. Bison will put this
48  * stuff into parse.h, so just declare, don't define. Sadly we can't have
49  * these things static :(
50  */
51 
52 /* Global .. the symbol whose definition we are currently parsing, the symbol
53  * which all defs in this parse action should be made local to.
54  */
55 extern Symbol *current_symbol;
56 extern Symbol *root_symbol;
57 
58 /* The current parse context.
59  */
60 extern Compile *current_compile;
61 extern ParseNode *current_parsenode;
62 
63 /* The kit we are adding new symbols to.
64  */
65 extern Toolkit *current_kit;
66 
67 /* Where it should go in the kit.
68  */
69 extern int tool_position;
70 
71 /* Lineno of start of last top-level def.
72  */
73 extern int last_top_lineno;
74 
75 /* Text we've gathered in this lex.
76  */
77 extern char lex_text_buffer[MAX_STRSIZE];
78 
79 /* Stack of symbols for parser - each represents a new scope level.
80  */
81 extern Symbol *scope_stack_symbol[MAX_SSTACK];
82 extern Compile *scope_stack_compile[MAX_SSTACK];
83 extern int scope_sp;
84 
85 /* Use to generate unique ids for anonymouse parse objects (eg. lambdas etc).
86  */
87 extern int parse_object_id;
88 
89 /* Get text for parsed objects.
90  */
91 char *input_text( char *out );
92 void input_reset( void );
93 void input_push( int n );
94 void input_backtoch( char ch );
95 void input_back1( void );
96 void input_pop( void );
97 
98 /* Nest and unnest scopes.
99  */
100 void scope_push( void );
101 void scope_pop( void );
102 void scope_pop_all( void );
103 void scope_reset( void );
104 
105 /* Helper functions.
106  */
107 void *parse_toplevel_end( Symbol *sym );
108 void *parse_access_end( Symbol *sym, Symbol *main );
109 
110 %}
111 
112 %union {
113 	struct sym_table *yy_symtab;
114 	ParseNode *yy_node;
115 	char *yy_name;
116 	ParseConst yy_const;
117 	UnOp yy_uop;
118 	BinOp yy_binop;
119 }
120 
121 %token TK_TAG TK_IDENT TK_CONST TK_DOTDOTDOT TK_LAMBDA TK_FROM TK_TO TK_SUCHTHAT
122 %token TK_UMINUS TK_UPLUS TK_POW
123 %token TK_LESS TK_LESSEQ TK_MORE TK_MOREEQ TK_NOTEQ
124 %token TK_LAND TK_LOR TK_BAND TK_BOR TK_JOIN TK_DIFF
125 %token TK_IF TK_THEN TK_ELSE
126 %token TK_CHAR TK_SHORT TK_CLASS TK_SCOPE
127 %token TK_INT TK_FLOAT TK_DOUBLE TK_SIGNED TK_UNSIGNED TK_COMPLEX
128 %token TK_SEPARATOR TK_DIALOG TK_LSHIFT TK_RSHIFT
129 
130 %type <yy_node> expr binop uop rhs list_expression comma_list body
131 %type <yy_node> simple_pattern complex_pattern list_pattern
132 %type <yy_node> leaf_pattern
133 %type <yy_node> crhs cexprlist prhs lambda
134 %type <yy_const> TK_CONST
135 %type <yy_name> TK_IDENT TK_TAG
136 
137 %left TK_SUCHTHAT
138 %left TK_LAMBDA
139 %nonassoc TK_IF
140 %left ','
141 %left TK_TO
142 %left TK_LOR
143 %left TK_LAND '@'
144 %left TK_BOR
145 %left '^'
146 %left TK_BAND
147 %nonassoc TK_EQ TK_NOTEQ TK_PEQ TK_PNOTEQ
148 %nonassoc TK_LESS TK_LESSEQ TK_MORE TK_MOREEQ
149 %left TK_LSHIFT TK_RSHIFT
150 %left '+' '-'
151 %left '*' '/' '%'
152 %left '!' '~' TK_JOIN TK_DIFF TK_UMINUS TK_UPLUS
153 %right TK_POW ':'
154 %right TK_CONST '('
155 %right TK_IDENT TK_TAG TK_SCOPE '['
156 %right TK_APPLICATION
157 %left '?' '.'
158 
159 %start select
160 
161 /*
162 
163   Our syntax for list comprehensions is not LALR(1). We have:
164 
165   	simple_pattern '<-' expr ';' |
166 	expr ';'
167 
168   simple_pattern can be something like
169 
170 	a:x
171 
172   which is also an expr. We don't know which branch to take until we see a
173   '<' or a ';'.
174 
175   Use bison's GLR system to parse this, and ignore the first 13 reduce/reduce
176   conflicts caused by this ambiguity.
177 
178   FIXME ... we now depend on bison, but we still have some yacc compatibility
179   stuff in here, and we don't use all of bison's nice features (eg. for
180   tracking line numbers in the source file). Fix this up at some stage.
181 
182  */
183 
184 %glr-parser
185 %expect-rr 13
186 
187 %error-verbose
188 
189 %%
190 
191 select:
192       	',' main |
193 	'^' single_definition |
194 	'*' params_plus_rhs optsemi {
195 		compile_check( current_compile );
196 	} |
197 	prhs {
198 		char buf[MAX_STRSIZE];
199 
200 		current_compile->tree = $1;
201 
202 		/* Junk any old text.
203 		 */
204 		IM_FREE( current_compile->text );
205 		IM_FREE( current_compile->prhstext );
206 		IM_FREE( current_compile->rhstext );
207 
208 		/* Set new text.
209 		 */
210 		IM_SETSTR( current_compile->rhstext, input_text( buf ) );
211 
212 		compile_check( current_compile );
213 	}
214 	;
215 
216 prhs:
217     	TK_BAND expr {
218 		$$ = $2;
219 	} |
220 	'@' cexprlist {
221 		$$ = $2;
222 	}
223 	;
224 
225 main:
226     	/* Empty */ |
227 	main single_definition
228 	;
229 
230 single_definition:
231       	directive {
232 		tool_position += 1;
233 	} |
234 	toplevel_definition optsemi {
235 		tool_position += 1;
236 	}
237 	;
238 
239 directive:
240 	TK_SEPARATOR {
241 		Tool *tool;
242 
243 		if( !is_top( current_symbol ) )
244 			yyerror( _( "not top level" ) );
245 
246 		tool = tool_new_sep( current_kit, tool_position );
247 		tool->lineno = input_state.lineno;
248 
249 		input_reset();
250 	} |
251 	TK_DIALOG TK_CONST TK_CONST {
252 		Tool *tool;
253 
254 		if( !is_top( current_symbol ) )
255 			yyerror( _( "not top level" ) );
256 
257 		/* Should have two strings.
258 		 */
259 		if( $2.type != PARSE_CONST_STR || $3.type != PARSE_CONST_STR )
260 			yyerror( _( "not strings" ) );
261 
262 		/* Add tool.
263 		 */
264 		tool = tool_new_dia( current_kit, tool_position,
265 			$2.val.str, $3.val.str );
266 		if( !tool )
267 			yyerror( error_get_sub() );
268 		tool->lineno = input_state.lineno;
269 
270 		/* Cast away const here.
271 		 */
272 		tree_const_destroy( (ParseConst *) &$2 );
273 		tree_const_destroy( (ParseConst *) &$3 );
274 
275 		input_reset();
276 	}
277 	;
278 
279 toplevel_definition:
280 	{
281 		last_top_lineno = input_state.lineno;
282 		scope_reset();
283 		current_compile = root_symbol->expr->compile;
284 	}
285 	definition {
286 		input_reset();
287 	}
288 	;
289 
290 /* Parse a new defining occurence. This can be a local or a top-level.
291  */
292 definition:
293    	simple_pattern {
294 		Symbol *sym;
295 
296 		/* Two forms: <name pattern-list rhs>, or <pattern rhs>.
297 		 * Enforce the no-args-to-pattern-assignment rule in the arg
298 		 * pattern parser.
299 		 */
300 		if( $1->type == NODE_LEAF ) {
301 			const char *name = IOBJECT( $1->leaf )->name;
302 
303 			/* Make a new defining occurence.
304 			 */
305 			sym = symbol_new_defining( current_compile, name );
306 
307 			(void) symbol_user_init( sym );
308 			(void) compile_new_local( sym->expr );
309 		}
310 		else {
311 			char name[256];
312 
313 			/* We have <pattern rhs>. Make an anon symbol for this
314 			 * value, then the variables in the pattern become
315 			 * toplevels which access that.
316 			 */
317 			if( !compile_pattern_has_leaf( $1 ) )
318 				yyerror( _( "left-hand-side pattern "
319 					"contains no identifiers" ) );
320 			im_snprintf( name, 256, "$$pattern_lhs%d",
321 				parse_object_id++ );
322 			sym = symbol_new_defining( current_compile, name );
323 			sym->generated = TRUE;
324 			(void) symbol_user_init( sym );
325 			(void) compile_new_local( sym->expr );
326 		}
327 
328 		/* Note on the enclosing last_sym. Things like the program
329 		 * window use this to work out what sym to display after a
330 		 * parse. symbol_dispose() is careful to NULL this out.
331 		 */
332 		current_compile->last_sym = sym;
333 
334 		/* Initialise symbol parsing variables. Save old current symbol,
335 		 * add new one.
336 		 */
337 		scope_push();
338 		current_symbol = sym;
339 		current_compile = sym->expr->compile;
340 
341 		g_assert( !current_compile->param );
342 		g_assert( current_compile->nparam == 0 );
343 
344 		/* Junk any old def text.
345 		 */
346 		IM_FREE( current_compile->text );
347 		IM_FREE( current_compile->prhstext );
348 		IM_FREE( current_compile->rhstext );
349 	}
350 	params_plus_rhs {
351 		compile_check( current_compile );
352 
353 		/* Link unresolved names into the outer scope.
354 		 */
355 		compile_resolve_names( current_compile,
356 			compile_get_parent( current_compile ) );
357 
358 		/* Is this the end of a top-level? Needs extra work to add to
359 		 * the enclosing toolkit etc.
360 		 */
361 		if( is_scope( symbol_get_parent( current_symbol ) ) )
362 			parse_toplevel_end( current_symbol );
363 
364 		/* Is this a pattern definition? Expand the pattern to a
365 		 * set of access defs.
366 		 */
367 		if( $1->type != NODE_LEAF ) {
368 			Compile *parent = compile_get_parent( current_compile );
369 			GSList *built_syms;
370 
371 			built_syms = compile_pattern_lhs( parent,
372 				current_symbol, $1 );
373 
374 			if( is_scope( symbol_get_parent( current_symbol ) ) )
375 				slist_map( built_syms,
376 					(SListMapFn) parse_toplevel_end, NULL );
377 			slist_map( built_syms,
378 				(SListMapFn) parse_access_end,
379 				current_symbol );
380 
381 			g_slist_free( built_syms );
382 		}
383 
384 		scope_pop();
385 	}
386 	;
387 
388 /* Parse params/body/locals into current_expr
389  */
390 params_plus_rhs:
391 	{
392 		input_push( 1 );
393 
394 		/* We've already read the character past the end of the
395 		 * identifier (that's why we know the identifier is over).
396 		 */
397 		input_back1();
398 	}
399 	params {
400 		input_push( 2 );
401 		input_backtoch( '=' );
402 	}
403 	body {
404 		current_compile->tree = $4;
405 		g_assert( current_compile->tree );
406 		input_push( 4 );
407 	}
408 	locals {
409 		char buf[MAX_STRSIZE];
410 
411 		input_pop();
412 
413 		/* Save body text as rhstext.
414 		 */
415 		IM_SETSTR( current_compile->rhstext, input_text( buf ) );
416 		input_pop();
417 
418 		/* Save params '=' body as prhstext.
419 		 */
420 		IM_SETSTR( current_compile->prhstext, input_text( buf ) );
421 		input_pop();
422 
423 		/* Save full text of definition.
424 		 */
425 		IM_SETSTR( current_compile->text, input_text( buf ) );
426 
427 #ifdef DEBUG
428 		printf( "%s->compile->text = \"%s\"\n",
429 			IOBJECT( current_compile->sym )->name,
430 			current_compile->text );
431 		printf( "%s->compile->prhstext = \"%s\"\n",
432 			IOBJECT( current_compile->sym )->name,
433 			current_compile->prhstext );
434 		printf( "%s->compile->rhstext = \"%s\"\n",
435 			IOBJECT( current_compile->sym )->name,
436 			current_compile->rhstext );
437 #endif /*DEBUG*/
438 	}
439 	;
440 
441 params:
442       	/* Empty */ |
443 	params simple_pattern {
444 		Symbol *sym;
445 
446 		/* If the pattern is just an identifier, make it a direct
447 		 * parameter. Otherwise make an anon param and put the pattern
448 		 * in as a local with the same id.
449 		 *
450 		 *	fred [a] = 12;
451 		 *
452 		 * parses to:
453 		 *
454 		 *	fred $$arg42 = 12 { $$patt42 = [a]; }
455 		 *
456 		 * A later pass creates the "a = $$arg42?0" definition.
457 		 */
458 		if( $2->type == NODE_LEAF ) {
459 			const char *name = IOBJECT( $2->leaf )->name;
460 
461 			/* Make defining occurence.
462 			 */
463 			sym = symbol_new_defining( current_compile, name );
464 			(void) symbol_parameter_init( sym );
465 		}
466 		else {
467 			char name[256];
468 
469 			im_snprintf( name, 256, "$$arg%d", parse_object_id );
470 			sym = symbol_new_defining( current_compile, name );
471 			sym->generated = TRUE;
472 			(void) symbol_parameter_init( sym );
473 
474 			im_snprintf( name, 256, "$$patt%d", parse_object_id++ );
475 			sym = symbol_new_defining( current_compile, name );
476 			sym->generated = TRUE;
477 			(void) symbol_user_init( sym );
478 			(void) compile_new_local( sym->expr );
479 			sym->expr->compile->tree = $2;
480 		}
481 	}
482 	;
483 
484 body :
485      	'=' TK_CLASS crhs {
486 		$$ = $3;
487 	} |
488 	rhs {
489 		$$ = $1;
490 	}
491 	;
492 
493 crhs:
494     	{
495 		ParseNode *pn = tree_class_new( current_compile );
496 
497 		input_push( 3 );
498 		scope_push();
499 		current_symbol = current_compile->super;
500 		current_compile = current_symbol->expr->compile;
501 
502 		current_parsenode = pn;
503 	}
504 	cexprlist {
505 		Compile *parent = compile_get_parent( current_compile );
506 		char buf[MAX_STRSIZE];
507 		int len;
508 
509 		(void) input_text( buf );
510 
511 		/* Always read 1 char too many.
512 		 */
513 		if( (len = strlen( buf )) > 0 )
514 			buf[len - 1] = '\0';
515 
516 		IM_SETSTR( current_compile->rhstext, buf );
517 		input_pop();
518 		current_compile->tree = $2;
519 
520 		if( current_compile->tree->elist )
521 			parent->has_super = TRUE;
522 
523 		/* Do some checking.
524 		 */
525 		compile_check( current_compile );
526 
527 		/* Link unresolved names.
528 		 */
529 		compile_resolve_names( current_compile, parent );
530 
531 		scope_pop();
532 
533 		$$ = current_parsenode;
534 		current_parsenode = NULL;
535 	}
536 	;
537 
538 rhs:
539    	'=' expr {
540 		$$ = $2;
541 	} |
542 	'=' expr ',' expr optsemi rhs {
543 		$$ = tree_ifelse_new( current_compile, $4, $2, $6 );
544 	}
545 	;
546 
547 locals:
548       	';' |
549 	'{' deflist '}' |
550 	'{' '}'
551 	;
552 
553 optsemi:
554        	/* Empty */ |
555 	';' optsemi
556 	;
557 
558 deflist:
559        	definition {
560 		input_pop();
561 		input_push( 5 );
562 	}
563 	optsemi |
564 	deflist definition {
565 		input_pop();
566 		input_push( 6 );
567 	}
568 	optsemi
569 	;
570 
571 cexprlist:
572 	/* Empty */ {
573 		$$ = tree_super_new( current_compile );
574 	} |
575 	cexprlist expr %prec TK_APPLICATION {
576 		$$ = tree_super_extend( current_compile, $1, $2 );
577 	}
578 	;
579 
580 expr:
581     	'(' expr ')' {
582 		$$ = $2;
583 	} |
584 	TK_CONST {
585 		$$ = tree_const_new( current_compile, $1 );
586 	} |
587 	TK_IDENT {
588 		$$ = tree_leaf_new( current_compile, $1 );
589 		im_free( $1 );
590 	} |
591 	TK_TAG {
592 		$$ = tree_tag_new( current_compile, $1 );
593 		im_free( $1 );
594 	} |
595 	TK_SCOPE {
596 		$$ = tree_leaf_new( current_compile,
597 			IOBJECT( symbol_get_scope( current_symbol ) )->name );
598 	} |
599 	TK_IF expr TK_THEN expr TK_ELSE expr %prec TK_IF {
600 		$$ = tree_ifelse_new( current_compile, $2, $4, $6 );
601 	} |
602 	expr expr %prec TK_APPLICATION {
603 		$$ = tree_appl_new( current_compile, $1, $2 );
604 	} |
605 	lambda |
606 	list_expression {
607 		$$ = $1;
608 	} |
609 	'(' expr ',' expr ')' {
610 		$$ = tree_binop_new( current_compile, BI_COMMA, $2, $4 );
611 	} |
612 	binop |
613 	uop
614 	;
615 
616 lambda:
617 	TK_LAMBDA TK_IDENT %prec TK_LAMBDA {
618 		char name[256];
619 		Symbol *sym;
620 
621 		/* Make an anonymous symbol local to the current sym, compile
622 		 * the expr inside that.
623 		 */
624 		im_snprintf( name, 256, "$$lambda%d", parse_object_id++ );
625 		sym = symbol_new_defining( current_compile, name );
626 		sym->generated = TRUE;
627 		(void) symbol_user_init( sym );
628 		(void) compile_new_local( sym->expr );
629 
630 		/* Initialise symbol parsing variables. Save old current symbol,
631 		 * add new one.
632 		 */
633 		scope_push();
634 		current_symbol = sym;
635 		current_compile = sym->expr->compile;
636 
637 		/* Make the parameter.
638 		 */
639 		sym = symbol_new_defining( current_compile, $2 );
640 		symbol_parameter_init( sym );
641 		im_free( $2 );
642 	}
643 	expr {
644 		Symbol *sym;
645 
646 		current_compile->tree = $4;
647 
648 		if( !compile_check( current_compile ) )
649 			yyerror( error_get_sub() );
650 
651 		/* Link unresolved names in to the outer scope.
652 		 */
653 		compile_resolve_names( current_compile,
654 			compile_get_parent( current_compile ) );
655 
656 		/* The value of the expr is the anon we defined.
657 		 */
658 		sym = current_symbol;
659 		scope_pop();
660 		$$ = tree_leafsym_new( current_compile, sym );
661 	}
662 	;
663 
664 list_expression:
665       	'[' expr TK_DOTDOTDOT ']' {
666 		$$ = tree_generator_new( current_compile, $2, NULL, NULL );
667 	} |
668 	'[' expr TK_DOTDOTDOT expr ']' {
669 		$$ = tree_generator_new( current_compile, $2, NULL, $4 );
670 	} |
671 	'[' expr ',' expr TK_DOTDOTDOT ']' {
672 		$$ = tree_generator_new( current_compile, $2, $4, NULL );
673 	} |
674 	'[' expr ',' expr TK_DOTDOTDOT expr ']' {
675 		$$ = tree_generator_new( current_compile, $2, $4, $6 );
676 	} |
677 	'[' expr TK_SUCHTHAT {
678 		char name[256];
679 		Symbol *sym;
680 		Compile *enclosing = current_compile;
681 
682 		/* Make an anonymous symbol local to the current sym, copy
683 		 * the map expr inside that.
684 		 */
685 		im_snprintf( name, 256, "$$lcomp%d", parse_object_id++ );
686 		sym = symbol_new_defining( current_compile, name );
687 		(void) symbol_user_init( sym );
688 		sym->generated = TRUE;
689 		(void) compile_new_local( sym->expr );
690 
691 		/* Push a new scope.
692 		 */
693 		scope_push();
694 		current_symbol = sym;
695 		current_compile = sym->expr->compile;
696 
697 		/* Somewhere to save the result expr. We have to copy the
698 		 * expr, as we want it to be bound in $$lcomp's context so
699 		 * that it can see the generators.
700 		 */
701 		sym = symbol_new_defining( current_compile, "$$result" );
702 		sym->generated = TRUE;
703 		sym->placeholder = TRUE;
704 		(void) symbol_user_init( sym );
705 		(void) compile_new_local( sym->expr );
706 		sym->expr->compile->tree = compile_copy_tree( enclosing, $2,
707 			sym->expr->compile );
708 	}
709 	generator frompred_list ']' {
710 		Symbol *sym;
711 
712 		/* The map expr can refer to generator names. Resolve inwards
713 		 * so it links to the generators.
714 		 */
715 		compile_resolve_names( compile_get_parent( current_compile ),
716 			current_compile );
717 
718 		/* Generate the code for the list comp.
719 		 */
720 		compile_lcomp( current_compile );
721 
722 		compile_check( current_compile );
723 
724 		/* Link unresolved names outwards.
725 		 */
726 		compile_resolve_names( current_compile,
727 			compile_get_parent( current_compile ) );
728 
729 		/* The value of the expr is the anon we defined.
730 		 */
731 		sym = current_symbol;
732 		scope_pop();
733 		$$ = tree_leafsym_new( current_compile, sym );
734 	} |
735 	'[' comma_list ']' {
736 		$$ = $2;
737 	} |
738 	'[' ']' {
739 		ParseConst elist;
740 
741 		elist.type = PARSE_CONST_ELIST;
742 		$$ = tree_const_new( current_compile, elist );
743 	}
744 	;
745 
746 frompred_list:
747 	/* Empty */ {
748 	} |
749      	frompred_list ';' frompred {
750 	}
751 	;
752 
753 generator:
754        simple_pattern TK_FROM expr {
755 		char name[256];
756 		Symbol *sym;
757 
758 		im_snprintf( name, 256, "$$pattern%d", parse_object_id );
759 		sym = symbol_new_defining( current_compile, name );
760 		sym->generated = TRUE;
761 		sym->placeholder = TRUE;
762 		(void) symbol_user_init( sym );
763 		(void) compile_new_local( sym->expr );
764 		sym->expr->compile->tree = $1;
765 
766 		im_snprintf( name, 256, "$$generator%d", parse_object_id++ );
767 		sym = symbol_new_defining( current_compile, name );
768 		sym->generated = TRUE;
769 		sym->placeholder = TRUE;
770 		(void) symbol_user_init( sym );
771 		(void) compile_new_local( sym->expr );
772 		sym->expr->compile->tree = $3;
773        }
774        ;
775 
776 frompred:
777        generator |
778        expr {
779 		char name[256];
780 		Symbol *sym;
781 
782 		im_snprintf( name, 256, "$$filter%d", parse_object_id++ );
783 		sym = symbol_new_defining( current_compile, name );
784 		sym->generated = TRUE;
785 		sym->placeholder = TRUE;
786 		(void) symbol_user_init( sym );
787 		(void) compile_new_local( sym->expr );
788 		sym->expr->compile->tree = $1;
789        }
790        ;
791 
792 comma_list:
793      	expr ',' comma_list {
794 		$$ = tree_lconst_extend( current_compile, $3, $1 );
795 	} |
796 	expr {
797 		$$ = tree_lconst_new( current_compile, $1 );
798 	}
799 	;
800 
801 /* How odd, break the "'+' { BI_ADD } | ..." into a separate production and we
802  * get reduce/reduce conflits. Copypaste a lot instead.
803  */
804 binop:
805      	expr '+' expr {
806 		$$ = tree_binop_new( current_compile, BI_ADD, $1, $3 );
807 	} |
808 	expr ':' expr {
809 		$$ = tree_binop_new( current_compile, BI_CONS, $1, $3 );
810 	} |
811 	expr '-' expr {
812 		$$ = tree_binop_new( current_compile, BI_SUB, $1, $3 );
813 	} |
814 	expr '?' expr {
815 		$$ = tree_binop_new( current_compile, BI_SELECT, $1, $3 );
816 	} |
817 	expr '/' expr {
818 		$$ = tree_binop_new( current_compile, BI_DIV, $1, $3 );
819 	} |
820 	expr '*' expr {
821 		$$ = tree_binop_new( current_compile, BI_MUL, $1, $3 );
822 	} |
823 	expr '%' expr {
824 		$$ = tree_binop_new( current_compile, BI_REM, $1, $3 );
825 	} |
826 	expr TK_JOIN expr {
827 		$$ = tree_binop_new( current_compile, BI_JOIN, $1, $3 );
828 	} |
829 	expr TK_POW expr {
830 		$$ = tree_binop_new( current_compile, BI_POW, $1, $3 );
831 	} |
832 	expr TK_LSHIFT expr {
833 		$$ = tree_binop_new( current_compile, BI_LSHIFT, $1, $3 );
834 	} |
835 	expr TK_RSHIFT expr {
836 		$$ = tree_binop_new( current_compile, BI_RSHIFT, $1, $3 );
837 	} |
838 	expr '^' expr {
839 		$$ = tree_binop_new( current_compile, BI_EOR, $1, $3 );
840 	} |
841 	expr TK_LAND expr {
842 		$$ = tree_binop_new( current_compile, BI_LAND, $1, $3 );
843 	} |
844 	expr TK_BAND expr {
845 		$$ = tree_binop_new( current_compile, BI_BAND, $1, $3 );
846 	} |
847 	expr '@' expr {
848 		$$ = tree_compose_new( current_compile, $1, $3 );
849 	} |
850 	expr TK_LOR expr {
851 		$$ = tree_binop_new( current_compile, BI_LOR, $1, $3 );
852 	} |
853 	expr TK_BOR expr {
854 		$$ = tree_binop_new( current_compile, BI_BOR, $1, $3 );
855 	} |
856 	expr TK_LESS expr {
857 		$$ = tree_binop_new( current_compile, BI_LESS, $1, $3 );
858 	} |
859 	expr TK_LESSEQ expr {
860 		$$ = tree_binop_new( current_compile, BI_LESSEQ, $1, $3 );
861 	} |
862 	expr TK_MORE expr {
863 		$$ = tree_binop_new( current_compile, BI_MORE, $1, $3 );
864 	} |
865 	expr TK_MOREEQ expr {
866 		$$ = tree_binop_new( current_compile, BI_MOREEQ, $1, $3 );
867 	} |
868 	expr TK_EQ expr {
869 		$$ = tree_binop_new( current_compile, BI_EQ, $1, $3 );
870 	} |
871 	expr TK_NOTEQ expr {
872 		$$ = tree_binop_new( current_compile, BI_NOTEQ, $1, $3 );
873 	} |
874 	expr TK_PEQ expr {
875 		$$ = tree_binop_new( current_compile, BI_PEQ, $1, $3 );
876 	} |
877 	expr TK_PNOTEQ expr {
878 		$$ = tree_binop_new( current_compile, BI_PNOTEQ, $1, $3 );
879 	} |
880 	expr '.' expr {
881 		$$ = tree_binop_new( current_compile, BI_DOT, $1, $3 );
882 	} |
883 	expr TK_DIFF expr {
884 		ParseNode *pn1, *pn2;
885 
886 		pn1 = tree_leaf_new( current_compile, "difference" );
887 		pn2 = tree_leaf_new( current_compile, "equal" );
888 		pn1 = tree_appl_new( current_compile, pn1, pn2 );
889 		pn1 = tree_appl_new( current_compile, pn1, $1 );
890 		pn1 = tree_appl_new( current_compile, pn1, $3 );
891 
892 		$$ = pn1;
893 	} |
894 	expr TK_TO expr {
895 		ParseNode *pn;
896 
897 		pn = tree_leaf_new( current_compile, "mknvpair" );
898 		pn = tree_appl_new( current_compile, pn, $1 );
899 		pn = tree_appl_new( current_compile, pn, $3 );
900 
901 		$$ = pn;
902 	}
903 	;
904 
905 signed:
906       	/* Nothing */ |
907 	TK_SIGNED
908 	;
909 
910 unsigned:
911 	/* Nothing */ |
912 	TK_UNSIGNED
913 	;
914 
915 uop:
916    	'(' unsigned TK_CHAR ')' expr %prec TK_UMINUS {
917 		$$ = tree_unop_new( current_compile, UN_CUCHAR, $5 );
918 	} |
919 	'(' TK_SIGNED TK_CHAR ')' expr %prec TK_UMINUS {
920 		$$ = tree_unop_new( current_compile, UN_CSCHAR, $5 );
921 	} |
922 	'(' signed TK_SHORT ')' expr %prec TK_UMINUS {
923 		$$ = tree_unop_new( current_compile, UN_CSSHORT, $5 );
924 	} |
925 	'(' TK_UNSIGNED TK_SHORT ')' expr %prec TK_UMINUS {
926 		$$ = tree_unop_new( current_compile, UN_CUSHORT, $5 );
927 	} |
928 	'(' signed TK_INT ')' expr %prec TK_UMINUS {
929 		$$ = tree_unop_new( current_compile, UN_CSINT, $5 );
930 	} |
931 	'(' TK_UNSIGNED TK_INT ')' expr %prec TK_UMINUS {
932 		$$ = tree_unop_new( current_compile, UN_CUINT, $5 );
933 	} |
934 	'(' TK_FLOAT ')' expr %prec TK_UMINUS {
935 		$$ = tree_unop_new( current_compile, UN_CFLOAT, $4 );
936 	} |
937 	'(' TK_DOUBLE ')' expr %prec TK_UMINUS {
938 		$$ = tree_unop_new( current_compile, UN_CDOUBLE, $4 );
939 	} |
940 	'(' TK_COMPLEX ')' expr %prec TK_UMINUS {
941 		$$ = tree_unop_new( current_compile, UN_CCOMPLEX, $4 );
942 	} |
943 	'(' TK_DOUBLE TK_COMPLEX ')' expr %prec TK_UMINUS {
944 		$$ = tree_unop_new( current_compile, UN_CDCOMPLEX, $5 );
945 	} |
946 	TK_UMINUS expr {
947 		$$ = tree_unop_new( current_compile, UN_MINUS, $2 );
948 	} |
949 	'!' expr {
950 		$$ = tree_unop_new( current_compile, UN_NEG, $2 );
951 	} |
952 	'~' expr {
953 		$$ = tree_unop_new( current_compile, UN_COMPLEMENT, $2 );
954 	} |
955 	TK_UPLUS expr {
956 		$$ = tree_unop_new( current_compile, UN_PLUS, $2 );
957 	}
958 	;
959 
960 /* Stuff that can appear on the LHS of an equals, or as a parameter pattern.
961  */
962 simple_pattern:
963 	leaf_pattern |
964 	'(' leaf_pattern ',' leaf_pattern ')' {
965 		$$ = tree_binop_new( current_compile, BI_COMMA, $2, $4 );
966 	} |
967 	simple_pattern ':' simple_pattern {
968 		$$ = tree_binop_new( current_compile, BI_CONS, $1, $3 );
969 	} |
970 	'(' complex_pattern ')' {
971 		$$ = $2;
972 	} |
973 	'[' list_pattern ']' {
974 		$$ = $2;
975 	} |
976 	'[' ']' {
977 		ParseConst elist;
978 
979 		elist.type = PARSE_CONST_ELIST;
980 		$$ = tree_const_new( current_compile, elist );
981 	}
982 	;
983 
984 /* Stuff that can appear in a complex (a, b) pattern.
985  */
986 leaf_pattern:
987 	TK_IDENT {
988 		$$ = tree_leaf_new( current_compile, $1 );
989 		im_free( $1 );
990 	} |
991 	TK_CONST {
992 		$$ = tree_const_new( current_compile, $1 );
993 	}
994 	;
995 
996 /* What can appear in round brackets or a comma list.
997  */
998 complex_pattern:
999 	TK_IDENT TK_IDENT {
1000 		$$ = tree_pattern_class_new( current_compile, $1,
1001 			tree_leaf_new( current_compile, $2 ) );
1002 		im_free( $1 );
1003 		im_free( $2 );
1004 	} |
1005 	simple_pattern
1006 	;
1007 
1008 list_pattern:
1009      	complex_pattern ',' list_pattern {
1010 		$$ = tree_lconst_extend( current_compile, $3, $1 );
1011 	} |
1012 	complex_pattern {
1013 		$$ = tree_lconst_new( current_compile, $1 );
1014 	}
1015 	;
1016 
1017 %%
1018 
1019 /* Return point on syntax error.
1020  */
1021 jmp_buf parse_error_point;
1022 
1023 /* Text we've lexed.
1024  */
1025 char lex_text_buffer[MAX_STRSIZE];
1026 VipsBuf lex_text = VIPS_BUF_STATIC( lex_text_buffer );
1027 
1028 /* State of input system.
1029  */
1030 InputState input_state;
1031 
1032 /* Defintions for the static decls at the top. We have to put the defs down
1033  * here to mkake sure they don't creep in to the generated parser.h.
1034  */
1035 
1036 /* Actually, we can't make these static :-( since they are declared extern at
1037  * the top of the file.
1038  */
1039 Symbol *current_symbol;
1040 Symbol *root_symbol;
1041 Compile *current_compile = NULL;
1042 ParseNode *current_parsenode = NULL;
1043 Toolkit *current_kit;
1044 int tool_position;
1045 int last_top_lineno;
1046 Symbol *scope_stack_symbol[MAX_SSTACK];
1047 Compile *scope_stack_compile[MAX_SSTACK];
1048 int scope_sp = 0;
1049 int parse_object_id = 0;
1050 
1051 /* Here for errors in parse.
1052  *
1053  * Bison calls yyerror with only a char* arg. This printf() version is called
1054  * from nip2 in a few places during parse.
1055  */
1056 void
nip2yyerror(const char * sub,...)1057 nip2yyerror( const char *sub, ... )
1058 {
1059 	va_list ap;
1060  	char buf[4096];
1061 
1062         va_start( ap, sub );
1063         (void) im_vsnprintf( buf, 4096, sub, ap );
1064         va_end( ap );
1065 
1066 	error_top( _( "Parse error." ) );
1067 
1068 	if( current_compile && current_compile->last_sym )
1069 		error_sub( _( "Error in %s: %s" ),
1070 			IOBJECT(  current_compile->last_sym )->name, buf );
1071 	else
1072 		error_sub( _( "Error: %s" ), buf );
1073 
1074 	longjmp( parse_error_point, -1 );
1075 }
1076 
1077 /* Bison calls this.
1078  */
1079 void
yyerror(const char * msg)1080 yyerror( const char *msg )
1081 {
1082 	nip2yyerror( "%s", msg );
1083 }
1084 
1085 /* Attach yyinput to a file.
1086  */
1087 void
attach_input_file(iOpenFile * of)1088 attach_input_file( iOpenFile *of )
1089 {
1090 	InputState *is = &input_state;
1091 
1092 #ifdef DEBUG
1093 	printf( "attach_input_file: \"%s\"\n", of->fname );
1094 #endif /*DEBUG*/
1095 
1096 	/* Need to clear flex/bison's buffers in case we abandoned the
1097 	 * previous parse.
1098 	 */
1099 	yyrestart( NULL );
1100 
1101 	is->of = of;
1102 	is->str = NULL;
1103 	is->strpos = NULL;
1104 	is->bwp = 0;
1105 	is->bspsp = 0;
1106 	is->bsp[is->bspsp] = 0;
1107 	is->lineno = 1;
1108 	is->charno = 0;
1109 	is->pcharno = 0;
1110 	is->charpos = 0;
1111 	is->oldchar = -1;
1112 
1113 	/* Init text gatherer.
1114 	 */
1115 	vips_buf_rewind( &lex_text );
1116 }
1117 
1118 /* Attach yyinput to a string.
1119  */
1120 void
attach_input_string(const char * str)1121 attach_input_string( const char *str )
1122 {
1123 	InputState *is = &input_state;
1124 
1125 #ifdef DEBUG
1126 	printf( "attach_input_string: \"%s\"\n", str );
1127 #endif /*DEBUG*/
1128 
1129 	yyrestart( NULL );
1130 
1131 	is->of = NULL;
1132 	is->str = (char *) str;
1133 	is->strpos = (char *) str;
1134 	is->bwp = 0;
1135 	is->bspsp = 0;
1136 	is->bsp[is->bspsp] = 0;
1137 	is->lineno = 1;
1138 	is->charno = 0;
1139 	is->pcharno = 0;
1140 	is->charpos = 0;
1141 	is->oldchar = -1;
1142 
1143 	/* Init text gatherer.
1144 	 */
1145 	vips_buf_rewind( &lex_text );
1146 }
1147 
1148 /* Read a character from the input.
1149  */
1150 int
ip_input(void)1151 ip_input( void )
1152 {
1153 	InputState *is = &input_state;
1154 	int ch;
1155 
1156 	if( is->oldchar >= 0 ) {
1157 		/* From unget buffer.
1158 		 */
1159 		ch = is->oldchar;
1160 		is->oldchar = -1;
1161 	}
1162 	else if( is->of ) {
1163 		/* Input from file.
1164 		 */
1165 		if( (ch = getc( is->of->fp )) == EOF )
1166 			return( 0 );
1167 	}
1168 	else {
1169 		/* Input from string.
1170 		 */
1171 		if( (ch = *is->strpos) )
1172 			is->strpos++;
1173 		else
1174 			/* No counts to update!
1175 			 */
1176 			return( 0 );
1177 	}
1178 
1179 	/* Update counts.
1180 	 */
1181 	if( ch == '\n' ) {
1182 		is->lineno++;
1183 		is->pcharno = is->charno + 1;
1184 		is->charno = 0;
1185 	}
1186 	is->charno++;
1187 	is->charpos++;
1188 
1189 	/* Add this character to the characters we have accumulated for this
1190 	 * definition.
1191 	 */
1192 	if( is->bwp >= MAX_STRSIZE )
1193 		yyerror( _( "definition is too long" ) );
1194 	if( is->bwp >= 0 )
1195 		is->buf[is->bwp] = ch;
1196 	is->bwp++;
1197 
1198 	/* Add to lex text buffer.
1199 	 */
1200 	if( is->charno > 0 )
1201 		vips_buf_appendc( &lex_text, ch );
1202 
1203 #ifdef DEBUG_CHARACTER
1204 	printf( "ip_input: returning '%c'\n", ch );
1205 #endif /*DEBUG_CHARACTER*/
1206 
1207 	return( ch );
1208 }
1209 
1210 /* Unget an input character.
1211  */
1212 void
ip_unput(int ch)1213 ip_unput( int ch )
1214 {
1215 	InputState *is = &input_state;
1216 
1217 #ifdef DEBUG_CHARACTER
1218 	printf( "ip_unput: ungetting '%c'\n", ch );
1219 #endif /*DEBUG_CHARACTER*/
1220 
1221 	/* Is lex trying to unget the end-of-file marker? Do nothing if it is.
1222 	 */
1223 	if( !ch )
1224 		return;
1225 
1226 	if( is->of ) {
1227 		if( ungetc( ch, is->of->fp ) == EOF )
1228 			error( "unget buffer overflow" );
1229 	}
1230 	else
1231 		/* Save extra char here.
1232 		 */
1233 		is->oldchar = ch;
1234 
1235 	/* Redo counts.
1236 	 */
1237 	if( ch == '\n' ) {
1238 		is->lineno--;
1239 
1240 		/* Restore previous charno.
1241 		 */
1242 		is->charno = is->pcharno;
1243 		is->pcharno = 0;
1244 	}
1245 	is->charno--;
1246 	is->charpos--;
1247 	is->bwp--;
1248 
1249 	/* Unget from lex text buffer.
1250 	 */
1251 	if( is->charno > 0 )
1252 		vips_buf_removec( &lex_text, ch );
1253 }
1254 
1255 /* Test for end-of-input.
1256  */
1257 gboolean
is_EOF(void)1258 is_EOF( void )
1259 {
1260 	InputState *is = &input_state;
1261 
1262 	if( is->of )
1263 		return( feof( is->of->fp ) );
1264 	else
1265 		return( *is->str == '\0' );
1266 }
1267 
1268 /* Return the text we have accumulated for the current definition. Remove
1269  * leading and trailing whitespace and spare semicolons. out needs to be
1270  * MAX_STRSIZE.
1271  */
1272 char *
input_text(char * out)1273 input_text( char *out )
1274 {
1275 	InputState *is = &input_state;
1276 	const char *buf = is->buf;
1277 
1278 	int start = is->bsp[is->bspsp];
1279 	int end = is->bwp;
1280 	int len;
1281 	int i;
1282 
1283 	for( i = start; i < end &&
1284 		(isspace( buf[i] ) || buf[i] == ';'); i++ )
1285 		;
1286 	start = i;
1287 	for( i = end - 1; i > start &&
1288 		(isspace( buf[i] ) || buf[i] == ';'); i-- )
1289 		;
1290 	end = i + 1;
1291 
1292 	len = end - start;
1293 
1294 	g_assert( len < MAX_STRSIZE - 1 );
1295 	im_strncpy( out, buf + start, len + 1 );
1296 	out[len] = '\0';
1297 
1298 #ifdef DEBUG_CHARACTER
1299 	printf( "input_text: level %d, returning \"%s\"\n",
1300 		is->bspsp, out );
1301 #endif /*DEBUG_CHARACTER*/
1302 
1303 	return( out );
1304 }
1305 
1306 /* Reset/push/pop input stacks.
1307  */
1308 void
input_reset(void)1309 input_reset( void )
1310 {
1311 	InputState *is = &input_state;
1312 
1313 #ifdef DEBUG_CHARACTER
1314 	printf( "input_reset:\n" );
1315 #endif /*DEBUG_CHARACTER*/
1316 
1317 	is->bwp = 0;
1318 	is->bspsp = 0;
1319 	is->bsp[0] = 0;
1320 	vips_buf_rewind( &lex_text );
1321 }
1322 
1323 void
input_push(int n)1324 input_push( int n )
1325 {
1326 	InputState *is = &input_state;
1327 
1328 #ifdef DEBUG_CHARACTER
1329 	printf( "input_push(%d): going to level %d, %d bytes into buffer\n",
1330 		n, is->bspsp + 1, is->bwp );
1331 
1332 	{
1333 		const int len = IM_MIN( is->bwp, 20 );
1334 		int i;
1335 
1336 		for( i = is->bwp - len; i < is->bwp; i++ )
1337 			if( is->buf[i] == '\n' )
1338 				printf( "@" );
1339 			else if( is->buf[i] == ' ' || is->buf[i] == '\t' )
1340 				printf( "_" );
1341 			else
1342 				printf( "%c", is->buf[i] );
1343 		printf( "\n" );
1344 		for( i = 0; i < len; i++ )
1345 			printf( "-" );
1346 		printf( "^\n" );
1347 	}
1348 #endif /*DEBUG_CHARACTER*/
1349 
1350 	is->bspsp += 1;
1351 	if( is->bspsp >= MAX_SSTACK )
1352 		error( "bstack overflow" );
1353 
1354 	is->bsp[is->bspsp] = is->bwp;
1355 }
1356 
1357 /* Yuk! We've just done an input_push() to try to grab the RHS of a
1358  * definition ... unfortunately, due to token readahead, we've probably
1359  * already read the start of the RHS.
1360  *
1361  * Back up the start point to just after the last ch character.
1362  */
1363 void
input_backtoch(char ch)1364 input_backtoch( char ch )
1365 {
1366 	InputState *is = &input_state;
1367 	int i;
1368 
1369 	for( i = is->bsp[is->bspsp] - 1; i > 0 && is->buf[i] != ch; i-- )
1370 		;
1371 
1372 	if( is->buf[i] == ch )
1373 		is->bsp[is->bspsp] = i + 1;
1374 }
1375 
1376 /* Move the last input_push() point back 1 character.
1377  */
1378 void
input_back1(void)1379 input_back1( void )
1380 {
1381 	InputState *is = &input_state;
1382 
1383 	if( is->bsp[is->bspsp] > 0 )
1384 		is->bsp[is->bspsp] -= 1;
1385 }
1386 
1387 void
input_pop(void)1388 input_pop( void )
1389 {
1390 	InputState *is = &input_state;
1391 
1392 #ifdef DEBUG_CHARACTER
1393 	printf( "input_pop: %d bytes into buffer\n", input_state.bwp );
1394 #endif /*DEBUG_CHARACTER*/
1395 
1396 	if( is->bspsp <= 0 )
1397 		error( "bstack underflow" );
1398 
1399 	is->bspsp--;
1400 }
1401 
1402 void
scope_push(void)1403 scope_push( void )
1404 {
1405 	if( scope_sp == MAX_SSTACK )
1406 		error( "sstack overflow" );
1407 
1408 	scope_stack_symbol[scope_sp] = current_symbol;
1409 	scope_stack_compile[scope_sp] = current_compile;
1410 	scope_sp += 1;
1411 }
1412 
1413 void
scope_pop(void)1414 scope_pop( void )
1415 {
1416 	if( scope_sp <= 0 )
1417 		error( "sstack underflow" );
1418 
1419 	scope_sp -= 1;
1420 	current_symbol = scope_stack_symbol[scope_sp];
1421 	current_compile = scope_stack_compile[scope_sp];
1422 }
1423 
1424 /* Back to the outermost scope.
1425  */
1426 void
scope_pop_all(void)1427 scope_pop_all( void )
1428 {
1429 	if( scope_sp > 0 ) {
1430 		scope_sp = 0;
1431 		current_symbol = scope_stack_symbol[scope_sp];
1432 		current_compile = scope_stack_compile[scope_sp];
1433 	}
1434 }
1435 
1436 /* Reset/push/pop parser stacks.
1437  */
1438 void
scope_reset(void)1439 scope_reset( void )
1440 {
1441 	scope_sp = 0;
1442 }
1443 
1444 /* End of top level parse. Fix up the symbol.
1445  */
1446 void *
parse_toplevel_end(Symbol * sym)1447 parse_toplevel_end( Symbol *sym )
1448 {
1449 	Tool *tool;
1450 
1451 	tool = tool_new_sym( current_kit, tool_position, sym );
1452 	tool->lineno = last_top_lineno;
1453 	symbol_made( sym );
1454 
1455 	return( NULL );
1456 }
1457 
1458 /* Built a pattern access definition. Set the various text fragments from the
1459  * def we are drived from.
1460  */
1461 void *
parse_access_end(Symbol * sym,Symbol * main)1462 parse_access_end( Symbol *sym, Symbol *main )
1463 {
1464 	IM_SETSTR( sym->expr->compile->rhstext,
1465 		main->expr->compile->rhstext );
1466 	IM_SETSTR( sym->expr->compile->prhstext,
1467 		main->expr->compile->prhstext );
1468 	IM_SETSTR( sym->expr->compile->text,
1469 		main->expr->compile->text );
1470 
1471 	return( NULL );
1472 }
1473 
1474 /* Interface to parser.
1475  */
1476 static gboolean
parse_input(int ch,Symbol * sym,Toolkit * kit,int pos)1477 parse_input( int ch, Symbol *sym, Toolkit *kit, int pos )
1478 {
1479 	current_kit = kit;
1480 	current_symbol = sym;
1481 	root_symbol = sym;
1482 	tool_position = pos;
1483 
1484 	scope_reset();
1485 	input_reset();
1486 
1487 	/* Signal start nonterminal to parser.
1488 	 */
1489 	ip_unput( ch );
1490 
1491 	if( setjmp( parse_error_point ) ) {
1492 		/* Restore current_compile.
1493 		 */
1494 		scope_pop_all();
1495 
1496 		if( current_compile )
1497 			compile_error_set( current_compile );
1498 
1499 		return( FALSE );
1500 	}
1501 	yyparse();
1502 
1503 	/* All ok.
1504 	 */
1505 	return( TRUE );
1506 }
1507 
1508 /* Parse the input into a set of symbols at a position in a kit.
1509  * kit may be NULL for no kit.
1510  */
1511 gboolean
parse_toplevel(Toolkit * kit,int pos)1512 parse_toplevel( Toolkit *kit, int pos )
1513 {
1514 	gboolean result;
1515 
1516 	current_compile = NULL;
1517 	result = parse_input( ',', kit->kitg->root, kit, pos );
1518 	iobject_changed( IOBJECT( kit ) );
1519 
1520 	return( result );
1521 }
1522 
1523 /* Parse a single top-level definition.
1524  */
1525 gboolean
parse_onedef(Toolkit * kit,int pos)1526 parse_onedef( Toolkit *kit, int pos )
1527 {
1528 	gboolean result;
1529 
1530 	current_compile = NULL;
1531 	result = parse_input( '^', kit->kitg->root, kit, pos );
1532 	iobject_changed( IOBJECT( kit ) );
1533 
1534 	return( result );
1535 }
1536 
1537 /* Parse new text into "expr". If params is set, str should be "a b = a+b"
1538  * (ie. include params), if not, then just rhs (eg. "a+b").
1539  */
1540 gboolean
parse_rhs(Expr * expr,ParseRhsSyntax syntax)1541 parse_rhs( Expr *expr, ParseRhsSyntax syntax )
1542 {
1543 	static const char start_ch_table[] = {
1544 		'&',		/* PARSE_RHS */
1545 		'*',		/* PARSE_PARAMS */
1546 		'@'		/* PARSE_SUPER */
1547 	};
1548 
1549 	char start_ch = start_ch_table[(int) syntax];
1550 	Compile *compile = compile_new_local( expr );
1551 
1552 	current_compile = compile;
1553 	if( !parse_input( start_ch, expr->sym, NULL, -1 ) ) {
1554 		current_compile = NULL;
1555 		return( FALSE );
1556 	}
1557 	current_compile = NULL;
1558 
1559 #ifdef DEBUG
1560 	printf( "parse_rhs:\n" );
1561 	dump_tree( compile->tree );
1562 #endif /*DEBUG*/
1563 
1564 	/* Resolve any dynamic refs.
1565 	 */
1566 	expr_resolve( expr );
1567 
1568 	/* Compile.
1569 	 */
1570 	if( compile_object( compile ) )
1571 		return( FALSE );
1572 
1573 	return( TRUE );
1574 }
1575 
1576 /* Free any stuff the lexer might have allocated.
1577  */
1578 void
free_lex(int yychar)1579 free_lex( int yychar )
1580 {
1581 	switch( yychar ) {
1582 	case TK_CONST:
1583 		tree_const_destroy( &yylval.yy_const );
1584 		break;
1585 
1586 	case TK_IDENT:
1587 	case TK_TAG:
1588 		IM_FREE( yylval.yy_name );
1589 		break;
1590 
1591 	default:
1592 		break;
1593 	}
1594 }
1595 
1596 /* Do we have a string of the form "IDENT = .."? Use the lexer to look along
1597  * the string checking components, return the IDENT if we do, NULL otherwise.
1598  */
1599 char *
parse_test_define(void)1600 parse_test_define( void )
1601 {
1602 	extern int yylex( void );
1603 	int yychar;
1604 	char *ident;
1605 
1606 	ident = NULL;
1607 
1608 	if( setjmp( parse_error_point ) ) {
1609 		/* Here for yyerror in lex.
1610 		 */
1611 		IM_FREE( ident );
1612 
1613 		return( NULL );
1614 	}
1615 
1616 	if( (yychar = yylex()) != TK_IDENT ) {
1617 		free_lex( yychar );
1618 
1619 		return( NULL );
1620 	}
1621 	ident = yylval.yy_name;
1622 
1623 	if( (yychar = yylex()) != '=' ) {
1624 		free_lex( yychar );
1625 		IM_FREE( ident );
1626 
1627 		return( NULL );
1628 	}
1629 
1630 	return( ident );
1631 }
1632 
1633 /* Do we have a string like "Workspaces.untitled.A1 = .."? Check for the
1634  * symbols as we see them, make the last one and return it. Used by --set.
1635  */
1636 Symbol *
parse_set_symbol(void)1637 parse_set_symbol( void )
1638 {
1639 	int yychar;
1640 	extern int yylex( void );
1641 	Compile *compile = symbol_root->expr->compile;
1642 	char *ident;
1643 	Symbol *sym;
1644 
1645 	ident = NULL;
1646 
1647 	if( setjmp( parse_error_point ) ) {
1648 		/* Here for yyerror in lex.
1649 		 */
1650 		IM_FREE( ident );
1651 		return( NULL );
1652 	}
1653 
1654 	do {
1655 		if( (yychar = yylex()) != TK_IDENT && yychar != TK_TAG ) {
1656 			free_lex( yychar );
1657 			yyerror( _( "identifier expected" ) );
1658 		}
1659 		ident = yylval.yy_name;
1660 
1661 		switch( (yychar = yylex()) ) {
1662 		case '.':
1663 			/* There's a dot, so we expect another identifier to
1664 			 * come. Look up this one and move to that context.
1665 			 */
1666 			if( !(sym = compile_lookup( compile, ident )) )
1667 				nip2yyerror( _( "'%s' does not exist" ),
1668 					ident );
1669 			if( !sym->expr ||
1670 				!sym->expr->compile )
1671 				nip2yyerror( _( "'%s' has no members" ),
1672 					ident );
1673 			compile = sym->expr->compile;
1674 			IM_FREE( ident );
1675 			break;
1676 
1677 		case '=':
1678 			/* This is the final identifier: create the symbol in
1679 			 * this context.
1680 			 */
1681 			sym = symbol_new_defining( compile, ident );
1682 			IM_FREE( ident );
1683 			break;
1684 
1685 		default:
1686 			free_lex( yychar );
1687 			yyerror( _( "'.' or '=' expected" ) );
1688 		}
1689 	} while( yychar != '=' );
1690 
1691 	return( sym );
1692 }
1693