On Fri Mar 30 07:44:12 EDT 2012, yari...@gmail.com wrote:
> "fn name @{block}" doesn't cause block to run in a sub-shell, although
> it accepts the syntax.
> Is it someting should not be tried, or something shoud be fixed?

you've misunderstood the current grammar.  you have defined 2 functions
name and '@' as {block}.  the binding, illustrated with parens is
        fn (name @) {block}
the production in the grammer is
        FN words brace
but since once production for words is words -> keyword, a keyword
is a valid function name.

so if you have

        fn @{echo hi, mom}

then

        ladd; fn @{echo hi, mom}                # space makes no difference
        ladd; whatis @
        fn @ {echo hi, mom}
        ladd; @
        ladd; '@'
        hi, mom

one could argue that this is a misfeature, since you can define
a function named 'for' or 'if' or '~' or '!'.  i don't currently see how 
disallowing
keywords in function names would be a problem, but it would
require at least 1 new production in the grammar.

note that "fn {echo bar}" is also legal, but doesn't do anything.

i've attached a change to the grammar that addresses this oddity.

- erik


----
broken! diffy -c syn.y
/n/dump/2012/0330/sys/src/cmd/rc/syn.y:29,35 - syn.y:29,35
        struct tree *tree;
  };
  %type<tree> line paren brace body cmdsa cmdsan assign epilog redir
- %type<tree> cmd simple first word comword keyword words wordsnl
+ %type<tree> cmd simple first 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
  %%
/n/dump/2012/0330/sys/src/cmd/rc/syn.y:81,88 - syn.y:81,88
  |     assign cmd %prec BANG   {$$=mung3($1, $1->child[0], $1->child[1], $2);}
  |     BANG cmd                {$$=mung1($1, $2);}
  |     SUBSHELL cmd            {$$=mung1($1, $2);}
- |     FN words brace          {$$=tree2(FN, $2, $3);}
- |     FN words                {$$=tree1(FN, $2);}
+ |     FN nkwords brace                {$$=tree2(FN, $2, $3);}
+ |     FN nkwords              {$$=tree1(FN, $2);}
  simple:       first
  |     simple word             {$$=tree2(ARGLIST, $1, $2);}
  |     simple redir            {$$=tree2(ARGLIST, $1, $2);}
/n/dump/2012/0330/sys/src/cmd/rc/syn.y:91,96 - syn.y:91,98
  word: keyword                 {lastword=1; $1->type=WORD;}
  |     comword
  |     word '^' word           {$$=tree2('^', $1, $3);}
+ nkword:       comword
+ |     word '^' word           {$$=tree2('^', $1, $3);}
  comword: '$' word             {$$=tree1('$', $2);}
  |     '$' word SUB words ')'  {$$=tree2(SUB, $2, $4);}
  |     '"' word                {$$=tree1('"', $2);}
/n/dump/2012/0330/sys/src/cmd/rc/syn.y:107,109 - syn.y:109,113
  |     
  words:                                {$$=(struct tree*)0;}
  |     words word              {$$=tree2(WORDS, $1, $2);}
+ nkwords:                              {$$=(struct tree*)0;}
+ |     nkwords nkword          {$$=tree2(WORDS, $1, $2);}

Reply via email to