** "Looks like JavaScript, brain (contents) is Ruby, (stability is AC / DC)" ** Scripting language Kinx ). The library is the life of the language. So how to use the library.
This time it's REPL.
At first, I was pessimistic that I couldn't do REPL, but I'd like to introduce something that works like that.
This is because if you execute ʻevel` obediently, the code area will swell evenly each time you execute it, so I introduced Isolate earlier. / 78cf553b65e286ea39c4) is now executed in a different context. Doing so has dramatically improved memory usage.
However, in this case, the context is different, so ** objects cannot be passed **. I managed to manage this by passing the class definition and function definition to ʻeval` every time. as a result,,,
function
/ native
), classes, and modules can be used as they are.[TAB]
key.[BS]
or [DEL]
. At least Japanese is OK.It was completed to the extent that. Worked hard...
What is REPL?
"What is a REPL?", => Read-Eval-Print-Loop. Read the input, ʻeval () `(evaluate), and display the result, and so on.
The REPL is built into the Kinx body, similar to SpecTest. Execute as follows.
$ ./kinx --exec:repl
kinx[ 0]> _
Since it is described in Markdown here, the color is different, but in reality, prompts and keywords are highlighted and displayed in color (both Windows and Linux).
At first I tried to put up an image so that I could understand it, but since it is still a demo, I tried hard to make a demo. ** Please praise someone **.
You can see that autocomplete (keyword completion) is also working properly. This area is difficult to understand without a demo. seeing is believing.
To get started, try the one listed here (Ruby that starts in 20 minutes) (https://www.ruby-lang.org/en/documentation/quickstart/). It's good, it's done properly at this level.
$ ./kinx --exec:repl
kinx[ 0]> "Hello, world"
=> "Hello, world"
kinx[ 1]> System.println("Hello, world")
Hello, world
=> (null)
kinx[ 2]> 3+2
=> 5
kinx[ 3]> 3*2
=> 6
kinx[ 4]> 3**2
=> 9
kinx[ 5]> Math.sqrt(9)
=> 3
kinx[ 6]> a = 3 ** 2
=> 9
kinx[ 7]> b = 4 ** 2
=> 16
kinx[ 8]> Math.sqrt(a+b)
=> 5
Then it is the main subject.
All commands start with .
.
command | Contents |
---|---|
.help |
View help |
.quit |
End |
.history |
Display command history |
.vars |
List of current variables |
.delete name |
From the current variable listname Delete variable |
.showdef name |
View function and class definitions |
.cursor [*on/off] |
Turn on cursor display/OFF (default ON) |
.fullcode [on/*off] |
Full input mode (default OFF),.run Do not execute until the command is entered |
.time [on/*off] |
Execution time measurement mode (default OFF), display execution time after execution |
.run |
Used to run in full input mode |
Please note that you can also exit with Ctrl-C
.
Type .help
to get the following help.
kinx[ 0]> .help
Kinx REPL Command: * means by default
.help Display this help.
.quit Quit REPL.
.history Display command history.
.vars Display variables with its value.
.delete name Delete a variable by name.
.showdef name Display function/class definition by name.
.cursor [*on|off] Set to 'off' to make the cursor invisible.
.fullcode [on|*off] Set to 'on', and the code will be executed by .run instead of immediately.
.time [on|*off] Set to 'on' to measure and display elapsed time.
.run Execute the code only with .fullcode 1.
REPL Operation:
[^] Arrow up Choose a previous command.
[v] Arrow down Choose a next command.
[<] Arrow left Move cursor to left.
[>] Arrow right Move cursor to right.
Ctrl+[<] Move cursor to left by word.
Ctrl+[>] Move cursor to right by word.
[DEL] Delete character on cursor.
[BS] Delete previous character.
[TAB] Move to the next tab stop, or auto-complete.
Use the left and right cursor keys to move the cursor, and Ctrl + left and right to move word by word. You can see the history with the up and down keys.
Basically, it accepts input with a line editor and immediately executes what you input.
kinx[ 0]> 10 * 2
=> 20
It automatically recognizes {
and the corresponding }
and continues editor mode until the entire block has been filled. At this time, the indent for 4 blanks is automatically added according to the number of {
.
However, you can only edit that line, so you cannot edit it after entering [Enter]
.
Use this feature to define function
, class
, module
, and so on.
kinx[ 0]> function func(...a) {
[ 1]> return a.reduce(&(r, e) => r + e);
[ 2]> }
=> function func
By doing this, you can use the function as follows.
kinx[ 0]> function func(...a) {
[ 1]> return a.reduce(&(r, e) => r + e);
[ 2]> }
=> function func
kinx[ 3]> func(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
=> 55
You can check the registered function as follows.
kinx[ 4]> .vars
function func(...a)
kinx[ 5]> .showdef func
function func(...a) {
return a.reduce(&(r, e) => r + e);
}
Commands and keywords are put into completion mode by pressing the [TAB]
key. Completion mode completes a string that may follow the preceding string in light gray. You can check it in the above demo that I tried hard to make. However, it would be troublesome to go back to the top, so I will post it again (because I made it).
If you press the [TAB]
key while this candidate is displayed, you can switch to the next candidate. At this time, the following key operations are performed.
[BS]
, [DEL]
key ... Confirms with the current candidate, and the cursor waits for input at that position.[Enter]
key ... Confirm on the fly or move to execute or next line.Completion candidates change depending on the context of the position. For example, if it is estimated to be an array from the past history, the method of ʻArrayis also added as a candidate. Also, if you assign an object instantiated with the
new` operator in the past history, the class method etc. will be added as candidates.
You can see some of this example in the demo shown at the beginning. For example, value
and sum
are displayed as candidates for s.
in the last line.
It may not work well in some cases, but if you enter a string halfway and press the [TAB]
key, candidates starting with that string will appear one after another, so try various things. Please give me.
Also, namespace
is not supported.
The .vars
command displays a list of variables that are currently enabled. Note that function names and class names are treated in the same column as variable names, so they cannot be registered with the same name. It will be overwritten with the one defined later.
kinx[ 20]> .vars
class Sample(...a)
a = 10
b = 20
c = 30
d = 40
e = 50
f = 60
g = 70
sample = new Sample(a, b, c, d, e, f, g)
You can specify and delete variables that you no longer need with the .delete
command. If you assign it to the same variable name, it will be overwritten, so you may not have much chance to use it. However, there are cases in which a Compile Error
occurs when the variable registration order is incorrect due to repeated overwriting, or when the variable dependency is incorrect due to the use of the .delete
command. In such a case, delete the variable that has become strange and re-register it so that it can operate correctly.
For example, there are cases where the above variables are registered as follows.
kinx[ 25]> .delete g //Remove g
kinx[ 26]> sample.sum() //The sample instance is malformed because g is gone.
=> Error: Compile Error.
kinx[ 27]> .vars
class Sample(...a)
a = 10
b = 20
c = 30
d = 40
e = 50
f = 60
sample = new Sample(a, b, c, d, e, f, g) // <-Illegal shape because g here is gone.
kinx[ 28]> g = 60 //I want to register a new g, but a compile error occurs.
=> Error: Compile Error.
kinx[ 29> .delete sample //A malformed instance is interfering with execution, so I removed that as well.
kinx[ 30]> g = 60 //g can be re-registered.
=> 60
kinx[ 31]> var sample = new Sample(a, b, c, d, e, f, g) //sample is also re-registered.
=> (null)
kinx[ 32]> sample.sum() //Can be executed using the new g.
=> 270
In .vars
, the function name and class name are displayed in the list display, but the definition is not displayed. You can then use the .showdef
command to see the contents of the definition.
kinx[ 33]> .showdef Sample
class Sample(...a) {
@value = a;
public sum() {
return @value.reduce(&(r, e) => r + e);
}
}
You can check the execution history so far with the .history
command. For example, the following display is displayed (the number is different from the above example, but it is a sample).
[ 0]: class Sample(...a) {
[ 1]: @value = a;
[ 2]: public sum() {
[ 3]: return @value.reduce(&(r, e) => r + e);
[ 4]: }
[ 5]: }
[ 6]: a = new Sample(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
[ 7]: .vars
[ 8]: System.println(a.sum());
[ 9]: a = 10
[ 10]: b = 20
[ 11]: c = 30
[ 12]: d = 40
[ 13]: e = 50
[ 14]: f = 60
[ 15]: g = 70
[ 16]: .vars
[ 17]: var sample = new Sample(a, b, c, d, e, f, g)
[ 18]: sample.sum()
[ 19]: .vars
[ 20]: sample.sum()
[ 21]: .showdef System
[ 22]: .showdef Sample
[ 23]: .vars
[ 24]: sample.sum()
[ 25]: .delete g
[ 26]: sample.sum()
[ 27]: .vars
[ 28]: g = 60
[ 29]: g = 60
[ 30]: .vars
[ 31]: .delete sample
[ 32]: g = 60
[ 33]: var sample = new Sample(a, b, c, d, e, f, g)
[ 34]: sample.sum()
[ 35]: .history
From the past history, you can also refer to it using !
As shown below.
kinx[ 36]> !34
=> "sample.sum();"
=> 270
You can also use the up and down cursor keys to select the history as a re-entry target.
If you set .time on
, the execution result will be displayed. Since the measurement result is simply the elapsed time until it is returned as ʻeval`, various overheads are included, but it will be a guide.
kinx[ 0]> native fib(n) {
[ 1]> return n if (n < 3);
[ 2]> return fib(n-2) + fib(n-1);
[ 3]> }
=> native<int> fib
kinx[ 4]> .time on
.time: on
kinx[ 5]> fib(39)
=> 102334155
elapsed: 1.238 s
kinx[ 6]> fib(34)
=> 9227465
elapsed: 0.131 s
With .fullcode on
, just pressing the[Enter]
key will not execute it. Continue typing until you enter the .run
command. However, at the moment, in full input mode, variables and class definitions are not ** registered **. All will be a one-shot execution of only that input.
kinx[ 0]> .fullcode on
.fullcode: on
kinx[ 1]> class Something() {
[ 2]> public println(...a) {
[ 3]> System.println(a);
[ 4]> }
[ 5]> }
[ 6]> s = new Something();
[ 7]> s.println(1, 2, 3, 4, 5, 6, 7, 8);
[ 8]> .run
[1, 2, 3, 4, 5, 6, 7, 8]
=> {"s":null}
kinx[ 9]> .vars
kinx[ 10]>
Use the .load
command to import an external file. Modules that are ʻusing as normal libraries are also loaded with
.load. You can enable some method name completion by loading it with
.load`.
For example, if you use DateTime
, you can do the following:
kinx[ 0]> .load DateTime
=> Successfully loaded.
kinx[ 1]> var dt = new DateTime(2020, 1, 1, 9, 30, 0)
=> (null)
kinx[ 2]> .vars
dt = new DateTime(2020, 1, 1, 9, 30, 00)
kinx[ 3]> dt.weekday()
=> 3
kinx[ 4]> System.println(dt)
2020/01/01 09:30:00
The search file name is specified name.kx
. The search target is performed in the following order. So you can also refer to the standard library.
lib
folder under the folder containing the kinx
executable filelib / std
folder under the folder containing the kinx
executable file../lib
folder as seen from the folder containing the kinx
executable filekinxlib
folder under the folder containing the kinx
executable filekinxlib / std
folder under the folder containing the kinx
executable fileExcuse me, with the v0.9.2 release I missed the consideration (5 and 6 were needed for Linux but not implemented) and on Linux I get an error
.load DateTime
. Specify.load /usr/bin/kinxlib/std/DateTime
as the workaround. It's hard. I'm sorry.
However, there are currently two caveats regarding DateTime. It may improve in future versions.
new
operator, but you must use the new
operator to complete method names.new DateTime ()
, but since it is newly new
for each execution, the value (time) to be acquired changes for each execution.East Asian Width
Supports UTF8 input. Since the cursor is moved according to the definition of East Asian Width, full-width characters are moved by that width.
In the following example, aiueo
also moves the cursor one character at a time in full-width, and Aiueo
moves the cursor in half-width. Also, deleting with the [DEL]
and [BS]
keys works correctly.
$ ./kinx --exec:repl
kinx[ 0]> a = "Aiueo Aiueo";
=> "Aiueo Aiueo"
kinx[ 1]> System.println(a);
Aiueo Aiueo
=> (null)
kinx[ 2]> a = "That kind of aio"; //On "U"[DEL]And on "O"[BS]Press.
=> "That kind of aio"
kinx[ 3]> System.println(a);
That kind of aio
=> (null)
I read somewhere that the programming language was ** half-serving without REPL **, so I tried my best to make it (it was hard ...). That said, it's still developing. With this as the first edition, I would like to make improvements if requested.
It would be great if more people could take this opportunity. We have also released a release build, so if you like.
See you next time.