
El lenguaje de secuencias de comandos de JMP, JSL, se basa en llamadas a funciones. Prácticamente todo lo que puede escribir en JSL es una llamada de función. Algunas cosas no parecen llamadas a funciones:
A = A + 3;
Es bastante obvio que el lado derecho de la instrucción de asignación es una expresión. Es menos obvio que la declaración de asignación en sí misma es una expresión.
E = expr ( A = A + 3 );
expr es un contenedor que puede usar alrededor de una expresión para evitar que la expresión se evalúe. E se establece en la expresión, no en el resultado evaluado de la expresión. Para echar un vistazo a E, utilice la función de cabeza. Head devolverá el nombre de la función en la raíz de la expresión:
show( head(E) );
Cabeza (E) = Asignar ();
Ahora ves que hay una función para hacer asignaciones:
Assign( testing, 3+4 );
7
show(testing)
prueba = 7;
Las expresiones en JSL son en realidad árboles. Aquí hay una imagen del árbol a=a+3, con la raíz en la parte superior y las hojas en la parte inferior:

Similar a la función Head, podemos usar la función Arg para acceder a los elementos secundarios de la función Assign:
show( arg(E,1) );
Arg(E, 1) = A; el lado izquierdo
show( arg(E,2) );
Arg(E, 2) = A + 3; el lado derecho
y cavando más profundo,
show(head(arg(E,2)))
Cabeza(Arg(E, 2)) = Añadir(); la cabeza del lado derecho
show(arg(arg(E,2),1))
Arg(Arg(E, 2), 1) = A; el lado izquierdo del plus
show(arg(arg(E,2),2))
Arg(Arg(E, 2), 2) = 3; el lado derecho del plus
Observe cómo el anidamiento de paréntesis describe el árbol. Este árbol solo tiene divisiones binarias. Hay una función, Narg , que devuelve el número de hijos. Devuelve 0 para los nodos hoja.
narg(E)
2 la función de asignación tiene dos argumentos, el lado izquierdo y el lado derecho
JMP por declaración es una llamada de función, tomando cuatro argumentos. Observe las comas que separan los argumentos, como cualquier otra función.
halfCats = 1;
for( iCat = 1, iCat <= 10, iCat++,
halfCats = halfCats / 2;
write( iCat, " ", halfCats , "\!n" )
);
1 0.5
2 0.25
3 0.125
4 0.0625
5 0.03125
6 0.015625
7 0.0078125
8 0.00390625
9 0.001953125
10 0.0009765625
Se necesitan tres comas para separar cuatro argumentos. En esto por declaración, el cuarto argumento son dos declaraciones, separadas por un punto y coma. Mire el cuarto argumento para ver si en realidad también es una función:
Head(
Arg(
Expr(
For( iCat = 1, iCat <= 10, iCat++,
halfCats = halfCats / 2;
Write( iCat, " ", halfCats, "\!n" );
)
),
4 /* the fourth arg */
)
);
Pegamento()
Pegamento es el nombre de la función que mantiene unida una secuencia de sentencias.Pegamento El primer argumento de es la primera declaración, etc.
Arg(
Arg(
Expr(
For( iCat = 1, iCat <= 10, iCat++,
halfCats = halfCats / 2;
Write( iCat, " ", halfCats, "\!n" );
)
),
4 /* the fourth arg is two statements, glued together */
),
1 /* the first arg is the first of the two glued statements */
);
mediogatos = mediogatos / 2
Una lista JSL es el mismo tipo de expresión:
list={33,44,55};
show(head(list));
show(narg(list));
show(arg(list,3));
Encabezado(lista) = {}; lista muestra corchetes para la cabeza, en lugar de un nombre como Asignar
N Arg(lista) = 3;
Arg(lista, 3) = 55;
Si solo desea el contenido de la lista, debe usar subíndices normales:
show(list[3]);
lista[3] = 55;
Pero a veces quieres hacer algo como convertir una lista en argumentos para una función.
En el Elefante post encontrará un ejemplo de cómo convertir una lista en un patrón (línea 5). Me está costando encontrar otro ejemplo tan bueno como ese, pero supongamos que desea verificar si la lista está en orden alfabético. El operador < de JMP puede hacer eso en una sola llamada de función:
LT = expr("a"<"b"<"c"<"d");
show(head(LT));
show(narg(LT));
Cabeza (LT) = Menos (); el operador menor que muestra un nombre de función, Menos
NArg(LT) = 4;
La función Less puede aceptar muchos argumentos, pero no es necesario que los escriba. Abajo, NombreExpr es recuperar la expresión almacenada en palabras, después de la Sustituir en modificó el { lista } ser - estar Menos (). JMP luego muestra la función Menos usando < para que sea más legible.
words =
{"Alpha", "Bravo", "Charlie", "Delta", "Echo", "Foxtrot", "Golf", "Hotel", "India",
"Juliet", "Kilo", "Lima", "Mike", "November", "Oscar", "Papa", "Quebec", "Romeo",
"Sierra", "Tango", "Uniform", "Victor", "Whiskey", "Xray", "Yankee", "Zulu"};
Substitute Into( words, Expr( {} ), Expr( Less() ) );
nameExpr(words);
"Alfa" < "Bravo" < "Charlie" < "Delta" < "Echo" < "Foxtrot" < "Golf" < "Hotel" <
"India" < "Julieta" < "Kilo" < "Lima" < "Mike" < "Noviembre" < "Oscar" < "Papá" <
"Quebec" < "Romeo" < "Sierra" < "Tango" < "Uniforme" < "Víctor" < "Whisky" < "Rayos" < "Yanqui" < "Zulú"
eval(words)
1 evaluar (palabras) devuelve 1, lo que indica que el resultado de Menos fue verdadero.
Otro ejemplo.
Actualización 28 de febrero de 2017: reparación del formato para la nueva comunidad
Craig, este artículo fue muy útil para mí en mi búsqueda continua de entender cómo manejar las expresiones.
De hecho, tenía una buena aplicación para su último truco, en el que convertía los elementos de una lista en argumentos de la función Less(). Quería generar una fórmula de columna que contenga la función Col Mean(), basada en la entrada del usuario desde una ventana de diálogo. La función Col Means() toma uno o más argumentos, y nunca he tenido una forma ingeniosa de sustituir una cantidad variable de argumentos (a menudo nombres de variables) en una función. Aquí están las líneas clave en mi guión:
arglist = {"altura", "edad", "sexo"}; // resultados de una ventana de diálogo
statformula = Substitute (arglist, Expr( {} ), Expr( Col Mean() ) ); // los elementos en la lista de argumentos se convierten en argumentos en la función Col Means()
newcol << Formula( Name Expr( statformula ) );
El script real es más complejo porque necesita lidiar con nombres de columnas desordenados que requieren Name(" "), pero se entiende la idea. Gracias por mostrarme este ingenioso truco.
Howard Rauch