On Sun May 14 08:32:47 PDT 2017, trebol55...@yandex.ru wrote:
>  > That isn't sh's rule. x=y is fine as an assignment without spaces.
> 
> Yes, sorry, in fact I was thinking on the contrary I wrote: don't set a 
> variable like in sh.
> 
> I like the use of spaces permitted in rc, as I said.

i was about to make this correction myself.  in any event, this is a sloppy but 
effective pure extension
to the grammar that allows everything but the first word to contain an '='.

since this is done at the grammar level, and not as one would expect at the 
lexer level, there are some
surprises like a function with "echo x=1" will deparse as echo 'x='^1.  not 
perfect, but workable

here's the code change

../rc/syn.y:24,35 - syn.y:24,47
        return !i;
  }
  
+ tree*
+ treeeq(int type, tree *c0, tree *c1)
+ {
+       char *old;
+ 
+       old = c0->str;
+       c0->str = smprint("%s=", c0->str);
+       c0->quoted = 1;
+       free(old);
+       return tree2(type, c0, c1);
+ }
+ 
  %}
  %union{
        struct tree *tree;
  };
  %type<tree> line paren brace body cmdsa cmdsan assign epilog redir
- %type<tree> cmd simple first word nkword comword keyword nkwords words wordsnl
+ %type<tree> cmd simple first nexteq word nkword comword keyword nkwords words 
wordsnl
  %type<tree> NOT FOR IN WHILE IF TWIDDLE BANG SUBSHELL SWITCH FN BREAK
  %type<tree> WORD REDIR DUP PIPE
  %%
../rc.me5/syn.y:84,89 - syn.y:96,102
  |     FN nkwords brace                {$$=tree2(FN, $2, $3);}
  |     FN nkwords              {$$=tree1(FN, $2);}
  simple:       first
+ |     simple nexteq           {$$=tree2(ARGLIST, $1, $2);}
  |     simple word             {$$=tree2(ARGLIST, $1, $2);}
  |     simple redir            {$$=tree2(ARGLIST, $1, $2);}
  first:        comword 
../rc.me5/syn.y:111,113 - syn.y:124,127
  |     words word              {$$=tree2(WORDS, $1, $2);}
  nkwords:                              {$$=(struct tree*)0;}
  |     nkwords nkword          {$$=tree2(WORDS, $1, $2);}
+ nexteq:       word '=' word           {$$=treeeq('^', $1, $3);}

here are some test cases

; ./o.rc
broken! x=1 echo $x
1
broken! whatis zot
zot: not found
broken! zot=1 echo $zot
1
broken! whatis one
one: not found
broken! one=1 two=2 echo $one $two
1 2
broken! echo one=1
one=1
broken! echo if=1
if=1
broken! fn eq {echo one=1 two=2}
broken! eq
one=1 two=2

- erik

Reply via email to