Thread overview
Til, a command language written in D
May 14, 2021
Cléber Zavadniak
May 14, 2021
Witold Baryluk
May 14, 2021
Cléber Zavadniak
May 18, 2021
kinke
Jun 06, 2021
Cléber Zavadniak
Jun 06, 2021
Cléber Zavadniak
May 14, 2021

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 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, 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

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 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, 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

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 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:)

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 18, 2021

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.

June 06, 2021

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...

June 06, 2021

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)