📜 ⬆️ ⬇️

Excellent data types in the language "Author"

In the “Author” interpreter, there are three different, classical, data type languages ​​that I want to talk about in this article, namely “digit”, “graf” and “program”. They are responsible, respectively, for astronomical numbers without a floating point, a universal graph and a tree of operators and function calls with variables and constants.

The following example demonstrates the main difference between the “digit” type and the “int” type.

 // fact.txt
 var fact (n) {return n <2? 1: n * fact (n-1);}

 void main () {
	 trace (fact (10));
	 trace (fact (50));
	 trace (fact ((digit) 50));
	 x = (digit) 1;
	 x.setAccuracy (63);
	 trace (x / 3.123);
	 getstring ();
 }


 3628800
 0
 30414093201713378043612608166064768844377641568960512000000000000
 0.320204931155939801472942683317323086775536343259686199167467178

')
In the first case, the calculation was correct. In the second, an overflow of memory occurred for the “int” type. In the third calculation passed without problems. This is due to the fact that the “digit” type is able to allocate memory for the exponent of a number as necessary. For the number mantissa, specify the limit to avoid memory leaks when dividing, say, by three. A method of the type “x.setAccuracy (63);” indicates the limitation of the mantissa number in decimal places. The type has other useful methods.

Now I will tell a little about the universal graph. A graph is a set of nodes and connections between them. For the type of "graf" node exists only when it has at least one connection. Each link has two node numbers, the corresponding value of the presence of input arrows and the name of the link. In addition to connections between nodes, in the universal graph, there is also a connection between a node and a marker. The marker is a string of text. Each link to a marker has one node number, a link name and a marker name. There are also logical values ​​for the presence of the input arrow in the node and in the marker.
The following program demonstrates the capabilities of the universal graph.

 // UniversalGraf.txt
 void main () {
	 // Set the graph (envelope).
	 G = (graf) 0;
	 G.NET (0.1, “expensive”, 1.1);
	 G.NET (0.1, "expensive", 1.4);
	 G.NET (1,1, "", 1,2);
	 G.NET (1.1, "", 1.4);
	 G.NET (1.1, "", 1.3);
	 G.NET (2.1, "", 1.3);
	 G.NET (2.1, "", 1.4);
	 G.NET (3.1, "", 1.4);
	 G.MARKER (0,0, "", 0, "Mars");
	 G.MARKER (1.0, "", 0, "Vinnitsa");
	 G.MARKER (2.0, "", 0, misto = "Guyvoron");
	 G.MARKER (3.0, "", 0, "Moscow");
	 G.MARKER (4.0, "", 0, "Gysin");
	 G.MARKER (0.1, "life", 0, "no");

	 trace (G.getMARKER (0, #, #, 0, #). export ());
	 trace (G.getNET (4, #, #, #, #). export ());

	 tracex (misto);
	 stop = n = G.getMARKER (#, 0, "", 0, misto) [0] [0];
	 do {
		 tracex ("->");
		 n = G.getNET (n, #, #, 1, #) [#] [2];
		 tracex (G.getMARKER (n, 0, "", 0, #) [0] [0]);
		 } while (stop! = n);

	 getstring ();
 }


 {{0, "", "Mars"}, {1, "life", "no"}}
 {{1, "expensive", 1.0}, {1, "", 1.1}, {1, "", 1.2}, {1, "", 1.3}}
 Gaivoron -> Moscow -> Vinnitsa -> Moscow -> Gaixing -> Gaivoron


To create a “graf” type variable, you need to use the type conversion operator. Next, we set the graph itself with a form similar to an open envelope. The “G.getMARKER (0, #, #, 0, #)” method searches through the links of the node with the marker using the specified mask and returns an array of the found elements. Each element is an array with the data requested in the mask. The search mask must contain at least one unknown link detail, which is indicated by the “#” symbol. In the “Author” language, the “#” symbol returns the “void” value, which can be obtained, for example, from a function without “return”. The array method ".export ()" converts the nested arrays into a string. The function "trace ()" displays a string on the screen. The method of the graph “G.getNET (4, #, #, #, #)” searches for connections between nodes of the graph, taking into account the symmetry of the search, and works similarly to the search for links with markers. When the type “void” falls into the array index operator “{3,5,9} [#]”, the interpreter returns one of the values ​​of the elements of this array, randomly equiprobable.
And this is a program that looks for ways to travel "around the world."
The type of graph also has other useful methods.
To demonstrate the capabilities of the fundamental type of “program”, I’ll give the following example.

 // demo.txt
 var main (nirvana, paradise, skazka) {
	 if (isset (nirvana)) return paradise + nirvana + skazka;
	 f = getFunction (getThisFunctionName ());
	 pos = f.Up (f.Root ());
	 command = command2 = f.getCommand (pos);
	 trace ((string) command + "==" + eval (command));
	 trace (command.getSub ({}));
	 trace (command.getSub ({0}));
	 trace (command.getSub ({0,0}));
	 trace (command.getSub ({0,1}));
	 trace (command.getSub ({1}));
	 trace ("-----------------");
	 pos = f.Up (pos);
	 command = f.getCommand (pos);
	 trace ((string) command + "==" + eval (command));
	 trace (command.getSub ({}));
	 trace (command.getSub ({0}));
	 trace (command.getSub ({0,2}));
	 trace (command.getSub ({0,4}));
	 trace (command.getSub ({0,4,0}));
	 trace (command.getSub ({0,4,3}));
	 trace (command.getSub ({0,4,3,0}));
	 trace (command.getSub ({0,4,3,1}));
	 trace (command.getSub ({1}));
	 trace ("-----------------");
	 proga = PROGRAM ("X = # + #");
	 trace (proga);
	 proga.setSub ({1,0}, command);
	 proga.setSub ({1,1}, command2);
	 trace (proga);
	 eval (proga);
	 trace ("X ==" + X);
	 getstring ();
	 return;
	 {0,1,2,3, main (100,20,7-3)} [4];
	 (1 + 9) * 100;
 }


 (1 + 9) * 100 == 1000
 (1 + 9) * 100
 1 + 9
 one
 9
 100
 -----------------
 {0,1,2,3, main (100,20,7-3)} [4] == 124
 {0,1,2,3, main (100,20,7-3)} [4]
 {0,1,2,3, main (100,20,7-3)}
 2
 main (100,20,7-3)
 main
 7-3
 7
 3
 four
 -----------------
 X = # + #
 X = {0,1,2,3, main (100,20,7-3)} [4] + (1 + 9) * 100
 X == 1124

The first line of the function algorithm indicates the terminal branch of recursion. Next, the variable "f" gets access to the function in which it is located. Then, the variable “pos” gets the unique identifier of the last node in the (block) scheme of the algorithm that the function turned into at the time of execution. The last node is above the zero node. Next, we get a copy of the command, which is located in the last node of the algorithm scheme. The “team” itself is an object of the “program” type. It is a tree of operators and function calls with variables and constants. Any command can be both converted to text and executed. With the help of the “command.getSub ({})” type method, you can copy a branch from a tree by specifying an access path, in this case the whole tree will be copied.
The “PROGRAM ()” function converts a string of program text into the “program” type.
The type has other useful methods.

more | There is a continuation.

Source: https://habr.com/ru/post/277195/


All Articles