www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.announce - Til, a command language written in D

reply =?UTF-8?B?Q2zDqWJlcg==?= Zavadniak <contato+til cleber.solutions> writes:
Hey, folks, how you doing?

2 months ago I started playing with a small personal project: 
creating a simple programming language / interpreter, both for 
fun and for learning more about... you know... creating a 
programming language / interpreter. :-)

Now, *I'm not exactly a Walter Bright*, so I decided to start 
with a **dynamic, Tcl-like language: command-based and without 
much "syntax"**. I tried to avoid the "*everything is a string*" 
concept and even played for some time with "*everything is a 
list*" (almost like Lisp, but with fewer parentheses) and even 
"*everything is a forward range*" - the results, then, were 
**horrible**, but, anyways... I've learned interesting lessons 
(specially: how important, powerful and versatile a simple STACK 
is).

[Til](https://github.com/til-lang/) is now mature enough, IMHO, 
to the point I'm spending more time writing documentation and 
"spreading the word" than coding that much. I published two 
packages on Dub (the language itself and a module) and created a 
[Github-Pages-Website](https://til-lang.github.io/til/), already.

I'm not pretentious in any form (I know it's just "*yet another 
language*"), but I'm actually very happy with the results: I can 
write programs in a interpreted language (I appreciate the power 
and development speed it gives me) and can extend it with another 
very nice (and powerful) language - D.

(Most other languages still follow the formula "extend it with C" 
and, although I consider myself a "C friendly" guy, that usually 
doesn't appeal that much to me..)


Anyway: the last thing I was working was **loading dynamic 
libraries as "modules"** and I stumbled across the potential 
problem of having two different GCs running independently. This 
article, https://dlang.org/articles/dll-linux.html , talks about 
linking the results (both the interpreter and the shared library) 
with `libphobos2.so` -- but it's nowhere to be found on my (Void) 
Linux system (and neither on FreeBSD). So I have some questions:

1- Should I compile a `libphobos2.so` "by hand"? Should I use 
`libphobos2-ldc-shared.so`???
2- Is the GC really going to run on my shared library after 
loading it? (I think that's maybe a "silly question", but also 
believe it's worth clarifying the matter.)


I appreciate any help.

(Furthermore, I'd like to thank to all people helping to make D a 
language (and ecosystem and community) even more amazing each 
day. :-)

(FurtherEvenMore: I'm new to the forum, so I hope I choose the 
right place to post this message...)
May 14 2021
next sibling parent reply Witold Baryluk <witold.baryluk gmail.com> writes:
On Friday, 14 May 2021 at 22:10:38 UTC, Cléber Zavadniak wrote:
 Hey, folks, how you doing?
Good. Hope you are doing good too.
 [Til](https://github.com/til-lang/) is now mature enough, IMHO, 
 to the point I'm spending more time writing documentation and 
 "spreading the word" than coding that much. I published two 
 packages on Dub (the language itself and a module) and created 
 a [Github-Pages-Website](https://til-lang.github.io/til/), 
 already.
Nice. Pretty clean syntax, and the implementation. I am not a fan of Tcl, but the Erlang influences are definitively cool. I like sub processes and the piping. Do you have some example of running external processes / commands. with `Til`? Composing pipes between external processes, and also between internal ones (maybe by some adapter that splits pipe data by lines?). A good alternative to bash is always welcome ;D
May 14 2021
parent =?UTF-8?B?Q2zDqWJlcg==?= Zavadniak <contato+til cleber.solutions> writes:
On Friday, 14 May 2021 at 22:18:50 UTC, Witold Baryluk wrote:

 Nice. Pretty clean syntax, and the implementation.
Thanks! I'm relatively new to D itself, I'll confess. Suggestions of improvements to the code are welcomed.
 I am not a fan of Tcl, but the Erlang influences are 
 definitively cool.
I myself find Tcl awesome. But it has a lot of flaws, too. I'm kind of trying to fix some of its issues, as well (the first versions of Til were labeled "a better Tcl"). (Also: a Tcl-based has the advantage that I can use its syntax highlighting satisfactorily on most of the cases.)
 I like sub processes and the piping.

 Do you have some example of running external processes / 
 commands.
 with `Til`? Composing pipes between external processes, and
 also between internal ones (maybe by some adapter that splits
 pipe data by lines?).
The module I published on Dub is [til_exec](https://code.dlang.org/packages/til_exec) and it runs commands and returns status and output, for now. (I'm trying to avoid the "giant standard library included" path, so I prefer to release modules separately.) There's a lot of things lacking right now, for sure: you can `exec` commands but there's no way, yet (future readers: please pay attention to the timestamp of this post. Thanks), of breaking the command output in multiple lines. (An example I can think would be the following, but `string.split` is the lacking part, currently:) ```tcl exec ls / | string.split "\n" | foreach line { io.out $line } ``` Interestingly, Til *pipes* were not born actually focused on handling external commands I/O, unix-shell-style, despite the obvious similarity. The first pipes implementation was an attempt to avoid Tcl sometimes-weird nested-commands syntax (used a lot for indexing) for instance, like `set parts [file split [file rootname $file_path]]`. But it evolved to be a way of handling **data** in general, while function parameters were supposed to define mostly **behavior**.
 A good alternative to bash is always welcome ;D
Yeah... I don't know... Not following this goal right now. `bash` is still out there for some very good reasons, as far as I can see. Some things are just expected in a shell, like expanding `*`, and usually general-purpose programming languages just feel weird handling "shell things". (But... who knows?...)
May 14 2021
prev sibling parent reply kinke <noone nowhere.com> writes:
On Friday, 14 May 2021 at 22:10:38 UTC, Cléber Zavadniak wrote:
 1- Should I compile a `libphobos2.so` "by hand"? Should I use 
 `libphobos2-ldc-shared.so`???
With LDC, -link-defaultlib-shared links the binary against shared druntime/Phobos. It's the default setting when creating a shared library with -shared; use it explicitly when creating an executable. This way, the executable and all .so libs share the same druntime/Phobos, incl. a single GC, default std.parallelism thread pool etc.
May 18 2021
parent reply =?UTF-8?B?Q2zDqWJlcg==?= Zavadniak <contato+til cleber.solutions> writes:
On Tuesday, 18 May 2021 at 15:19:50 UTC, kinke wrote:
 On Friday, 14 May 2021 at 22:10:38 UTC, Cléber Zavadniak wrote:
 1- Should I compile a `libphobos2.so` "by hand"? Should I use 
 `libphobos2-ldc-shared.so`???
With LDC, -link-defaultlib-shared links the binary against shared druntime/Phobos. It's the default setting when creating a shared library with -shared; use it explicitly when creating an executable. This way, the executable and all .so libs share the same druntime/Phobos, incl. a single GC, default std.parallelism thread pool etc.
Tried that for both a shared library (libtil_exec.so) and the interpreter itself but with LDC2 it keeps throwing this: object.Exception source/til/modules.d(100): dlsym error: Library ../til/til.debug is not already loaded "../til/til.debug" is the interpreter executable. The intepreter try to load the name "getCommands" from the shared library with: auto getCommands = cast(CommandHandlerMap function(Process))dlsym( lh, "getCommands" ); (https://github.com/til-lang/til/blob/8213ab61b87a478f9b2d140a370a870dc9bb0fc9/source/til/modules.d#L94) Using DMD, everything goes smooth... `objdump -T libtil_exec.so` shows the name is there as it should in the shared library: 000000000006df40 g DF .text 0000000000000069 getCommands LDC2 info: $ ldc2 --version LDC - the LLVM D compiler (1.26.0): based on DMD v2.096.1 and LLVM 12.0.0 built with DMD64 D Compiler v2.095.0 Default target: x86_64-unknown-linux-musl Host CPU: skylake Trying to figure out what's happening, here, but any help is welcome...
Jun 05 2021
parent =?UTF-8?B?Q2zDqWJlcg==?= Zavadniak <contato+til cleber.solutions> writes:
Heeey! Fixed it! Thanks to this 2016 thread: 
https://forum.dlang.org/post/o3tvfh$1lvk$1 digitalmars.com

In short:

1. call `dlerror()` to clean up any eventual old error messages 
(just in case);
2. do **not** look into `lh` (the "library handler") to check for 
errors, because it **can** be null even without any error (see 
Jacob Carlborg answer on that thread)
3. after calling `dlopen`, using the result of another call to 
`dlerror()` to check for errors (it should be NULL if everything 
went okay).



Yay! Now I can create modules linked against `libphobos2` shared 
library!

     ldd libtil_exec.so
         ldd (0x7f8ccd0d9000)
         libphobos2-ldc-shared.so.96 => 
/usr/lib/libphobos2-ldc-shared.so.96 (0x7f8cccb6b000)
         libdruntime-ldc-shared.so.96 => 
/usr/lib/libdruntime-ldc-shared.so.96 (0x7f8ccca0e000)
         libunwind.so.1 => /usr/lib/libunwind.so.1 (0x7f8ccc9f7000)
         libc.so => ldd (0x7f8ccd0d9000)
Jun 05 2021