Hi, Actually I'm thinking about a patch which will load these usercmds from the config file at the startup. In this case every user will be able to create own commands (like ]pwd and ]cd below) to interact with interpreter and store them independent of the workspaces.
It will definitely helpful for me, what about others? Christian Robert <christian.rob...@polymtl.ca> writes: > It would be fun if those ]USERCMD could be saved in workspace and )loaded > back. > > Not sure if it's possible ... > > Xtian. > > > On 2017-02-23 12:04, Juergen Sauermann wrote: >> Hi Alexey, Blake, >> >> I have applied the patch, *SVN 892*. >> >> I don't think that it hurts too much even though its not APL. >> Nor are lambdas, so the ⍎ of )COMMANDs and {...} should fit nicely. >> >> /// Jürgen >> >> >> On 02/23/2017 08:47 AM, Alexey Veretennikov wrote: >>> Hi, >>> >>> I'm updating the ]USERCMD functionality which is already non-standard >>> extension in GNU >>> APL. Similar extension exists in Dyalog APL for quite many years as >>> well. These commands targeted use in the interpreter and have nothing to do >>> with a new syntax. >>> What I did is just fixed its limitation where I always had to >>> create a named function to add a user command. >>> >>> P.S. Example with ]pwd was bogus, the proper one is >>> >>> ]usercmd ]pwd {⎕FIO 30 ⍵} >>> User-defined command ]pwd installed. >>> ]pwd >>> /Users/alexeyv >>> >>> >>> Blake McBride <blake1...@gmail.com> writes: >>> >>>> Not sure I like this. Doesn't seem like APL. You are mangling >>>> program-ability with system commands. APL >>>> has no history of that. It may be an okay idea, but it's not APL. >>>> >>>> Adding program-ability to system commands is essentially adding a whole new >>>> syntax to APL. >>>> >>>> Just one opinion. >>>> >>>> Blake >>>> >>>> On Wed, Feb 22, 2017 at 4:18 PM, Alexey Veretennikov >>>> <alexey.veretenni...@gmail.com> wrote: >>>> >>>> Hi, >>>> >>>> The proposed patch allows usage of dfns as a ]USERCMD. >>>> The mode (monadic or dyadic) is not needed since it is derived from the >>>> lambda function itself. >>>> >>>> Possibility to use lambdas as a user commands allows to have commands >>>> without polluting the global namespace with the function names. >>>> >>>> Usage example: >>>> >>>> ]usercmd ]pwd {⎕FIO 30 ⍵ ← ⍺} >>>> User-defined command ]pwd installed. >>>> >>>> ]pwd >>>> /Users/alexeyv/Sources/apl-svn/src >>>> >>>> ]usercmd ]cd {⎕FIO[54] (⎕IO+1) ⊃ ⍵ ← ⍺} >>>> User-defined command ]cd installed. >>>> >>>> ]cd /Users/alexeyv >>>> 0 >>>> >>>> ]pwd >>>> /Users/alexeyv >>>> >>>> -- >>>> Br, >>>> /Alexey >>>> >>>> Index: src/Command.cc >>>> =================================================================== >>>> --- src/Command.cc (revision 891) >>>> +++ src/Command.cc (working copy) >>>> @@ -1277,6 +1277,7 @@ >>>> // ]USERCMD REMOVE ]existing-command >>>> // ]USERCMD ]new-command APL-fun >>>> // ]USERCMD ]new-command APL-fun mode >>>> + // ]USERCMD ]new-command LAMBDA-fun >>>> // >>>> if (args.size() == 0) >>>> { >>>> @@ -1321,14 +1322,54 @@ >>>> return; >>>> } >>>> >>>> - if (args.size() > 3) >>>> + // check if the user command is not followed by the string >>>> + if (args.size() == 1) >>>> + { >>>> + out << "BAD COMMAND+" << endl; >>>> + MORE_ERROR() << "user command syntax in ]USERCMD: ]new-command APL-fun >>>> [mode]"; >>>> + return; >>>> + } >>>> + UCS_string command_name = args[0]; >>>> + UCS_string apl_fun = args[1]; >>>> + int mode = 0; >>>> + >>>> + // check if lambda >>>> + bool is_lambda = false; >>>> + if (apl_fun[0] == '{') >>>> { >>>> + // looks like the user command is a lambda function. >>>> + UCS_string result; >>>> + // lambdas could contain spaces, collect all arguments in one string >>>> + for (int i = 1; i < args.size(); ++ i) >>>> + { >>>> + result << args[i]; >>>> + } >>>> + // check if lamda-function closed properly >>>> + if (result.last() == '}') >>>> + { >>>> + is_lambda = true; >>>> + apl_fun = result; >>>> + // determine the mode: if both alpha and omega present, assume dyadic, >>>> + // otherwise - monadic usage >>>> + mode = (apl_fun.contains(UNI_OMEGA) && apl_fun.contains(UNI_ALPHA)) ? 1 >>>> : 0; >>>> + } >>>> + else >>>> + { >>>> + out << "BAD COMMAND+" << endl; >>>> + MORE_ERROR() << "not found closing } in lambda function"; >>>> + return; >>>> + } >>>> + } >>>> + >>>> + if (args.size() > 3 && !is_lambda) >>>> + { >>>> out << "BAD COMMAND+" << endl; >>>> MORE_ERROR() << "too many parameters in command ]USERCMD"; >>>> return; >>>> } >>>> >>>> -const int mode = (args.size() == 3) ? args[2].atoi() : 0; >>>> + // check mode >>>> + if (!is_lambda && args.size() == 3) mode = args[2].atoi(); >>>> if (mode < 0 || mode > 1) >>>> { >>>> out << "BAD COMMAND+" << endl; >>>> @@ -1339,11 +1380,11 @@ >>>> >>>> // check command name >>>> // >>>> - loop(c, args[0].size()) >>>> + loop(c, command_name.size()) >>>> { >>>> bool error = false; >>>> - if (c == 0) error = error || args[0][c] != ']'; >>>> - else error = error || !Avec::is_symbol_char(args[0][c]); >>>> + if (c == 0) error = error || command_name[c] != ']'; >>>> + else error = error || !Avec::is_symbol_char(command_name[c]); >>>> if (error) >>>> { >>>> out << "BAD COMMAND+" << endl; >>>> @@ -1355,28 +1396,31 @@ >>>> // check conflicts with existing commands >>>> // >>>> #define cmd_def(cmd_str, _cod, _arg, _hint) \ >>>> - if (check_name_conflict(out, cmd_str, args[0])) return; >>>> + if (check_name_conflict(out, cmd_str, command_name)) return; >>>> #include "Command.def" >>>> - if (check_redefinition(out, args[0], args[1], mode)) >>>> + if (check_redefinition(out, command_name, apl_fun, mode)) >>>> { >>>> out << " User-defined command " >>>> - << args[0] << " installed." << endl; >>>> + << command_name << " installed." << endl; >>>> return; >>>> } >>>> >>>> // check APL function name >>>> - // >>>> - loop(c, args[1].size()) >>>> + // Only needed when not a lambda function >>>> + if (!is_lambda) >>>> { >>>> - if (!Avec::is_symbol_char(args[1][c])) >>>> - { >>>> - out << "BAD COMMAND+" << endl; >>>> - MORE_ERROR() << "bad APL function name in command ]USERCMD"; >>>> - return; >>>> - } >>>> + loop(c, apl_fun.size()) >>>> + { >>>> + if (!Avec::is_symbol_char(apl_fun[c])) >>>> + { >>>> + out << "BAD COMMAND+" << endl; >>>> + MORE_ERROR() << "bad APL function name in command ]USERCMD"; >>>> + return; >>>> + } >>>> + } >>>> } >>>> >>>> -user_command new_user_command = { args[0], args[1], mode }; >>>> +user_command new_user_command = { command_name, apl_fun, mode }; >>>> user_commands.append(new_user_command); >>>> >>>> out << " User-defined command " >>>> >>>> >> > -- Br, /Alexey