Re: What parser generator can let me run arbitrary code in its match rules?

2023-11-20 Thread Julian Fondren via Digitalmars-d-learn
On Monday, 20 November 2023 at 23:50:24 UTC, Dmitry Ponyatov 
wrote:

- not abandoned years ago
- documentation and commented samples presenets
- CTFE the best


https://code.dlang.org/packages/pegged


Re: What parser generator can let me run arbitrary code in its match rules?

2023-11-20 Thread Guillaume Piolat via Digitalmars-d-learn
On Monday, 20 November 2023 at 23:56:36 UTC, Dmitry Ponyatov 
wrote:
Or maybe someone advice me some set of books deeply targets for 
learning of binary and symmetric parsing (such as binpac), DCG 
in C or using generators in D, etc to let me write my own lib.


'Crafting Interpreters' book explain recursive descent parser, 
including parsing binary operators with priorities.


Re: What parser generator can let me run arbitrary code in its match rules?

2023-11-20 Thread Dmitry Ponyatov via Digitalmars-d-learn
Or maybe someone advice me some set of books deeply targets for 
learning of binary and symmetric parsing (such as binpac), DCG in 
C or using generators in D, etc to let me write my own lib.


Everething I found (besides the Dragon book) uses black magic 
with Haskell, Lisp etc.


What parser generator can let me run arbitrary code in its match rules?

2023-11-20 Thread Dmitry Ponyatov via Digitalmars-d-learn

- not abandoned years ago
- documentation and commented samples presenets
- CTFE the best


Re: What is :-) ?

2023-11-20 Thread Julian Fondren via Digitalmars-d-learn

On Monday, 20 November 2023 at 16:09:33 UTC, Antonio wrote:

**Why this is a function and not a delegate?**

```auto createCounter = (int nextValue) => (int dummy) => 
nextValue++;```


Syntactically I dont see any difference:


`createCounter` is a function, and not a delegate, as it doesn't 
close over any variables. It returns a delegate as the variable 
`nextValue` is closed over. There's no difference in syntax. The 
difference is however important as an environment must be 
retained for the closed-over variables and passed along with the 
pointer, making delegates both more expensive and incompatible 
with function pointers on the C ABI. Note that `f` and `g` are 
obviously not pointing to the same `nextValue`:


```d
auto createCounter = (int nextValue) => () => nextValue++;

void main() {
import std.stdio : writeln;

auto f = createCounter(5);
auto g = createCounter(0);
writeln(f()); // 5
writeln(g()); // 0
writeln(f()); // 6
writeln(g()); // 1
}
```

What "breaks" my mind is that a compiler decision (treat a 
piece of code as function or delegate) is not completely 
transparent


D is trying to be convenient (by offering delegates at all, and 
by making the syntax so light) while offering fine control (by 
letting you distinguish between function pointers and delegates). 
It'd be a much simpler language if it dropped one of those aims, 
but such languages also already exist.


Similarly D also distinguishes between "numbers" (`int`) and 
"numbers" (`double`) and this can also be transparent and also 
cause 'side effects'. Someone educated in mathematics but not 
familiar with computing might complain about


```d
void main() {
import std.stdio : writefln;
auto n = 1;
writefln!"%d"(n);
}
```

breaking when "all I did was bump n by one-tenth, to 1.1".

I'm not trying to be mean with this example, and I don't think 
it's shameful either to know mathematics but not computing. But D 
expects you to be familiar with such things for you to not be 
surprised by how it behaves.


Re: What is :-) ?

2023-11-20 Thread Paul Backus via Digitalmars-d-learn

On Monday, 20 November 2023 at 16:09:33 UTC, Antonio wrote:
What "breaks" my mind is that a compiler decision (treat a 
piece of code as function or delegate) is not completely 
transparent causing "side" effects on your code  (writeln 
doesn't work the same way:  it shows the delegate signature, 
but not the function signature).


It's certainly surprising that `writeln` treats function pointers 
and delegates differently. My guess is that it's because 
[`isPointer`][1] returns `true` for functions and `false` for 
delegates.


[1]: https://phobos.dpldocs.info/std.traits.isPointer.html

Is there any way to force D compiler to treat this 
"createCounter" declaration as **delegate** instead of 
**function**?


```d
  auto createCounter = (int nextValue) => () => nextValue++;
```


You can put the `delegate` keyword in front of the function 
literal:


```d
auto createCounter = delegate (int nextValue) => () => 
nextValue++;

```

This syntax is documented in the spec's section on [Function 
Literals][2] (look at the grammar box and the examples).


[2]: https://dlang.org/spec/expression.html#function_literals


Re: What is :-) ?

2023-11-20 Thread evilrat via Digitalmars-d-learn

On Monday, 20 November 2023 at 16:09:33 UTC, Antonio wrote:


Is there any way to force D compiler to treat this 
"createCounter" declaration as **delegate** instead of 
**function**?


```d
  auto createCounter = (int nextValue) => () => nextValue++;
```


generally there is a way to tell the compiler specifically that 
you want a delegate or a function, and additionally there is 
`toDelegate` function from std.functional that could be useful in 
some cases.


https://dlang.org/phobos/std_functional.html#toDelegate


the syntax for specifying delegate/function is smth like this, 
IIRC return type can be omitted but for reference I write it here 
as auto.


```d
// this is a function returning a delegate
auto createCounter(int nextValue) => auto delegate() => 
nextValue++;


// this is a function returning a function
auto createCounter(int nextValue) => auto function() => 
nextValue++;

```


Re: What is :-) ?

2023-11-20 Thread Antonio via Digitalmars-d-learn

On Monday, 20 November 2023 at 13:25:48 UTC, Paul Backus wrote:

On Monday, 20 November 2023 at 08:47:34 UTC, Antonio wrote:
- What is the way to do ```writeln``` work with ```Counter``` 
function the same way it works with ```next``` function?


`writeln()` should do it.


It does not do the same:  It shows an address, not the function 
signature.


Because I need to understand "why", I propose a second example 
(with some additional info based on @evilrat proposals :-) ):


```d
import std.stdio;

void main()
{
  auto createCounter = (int nextValue) => (int dummy) => 
nextValue++;

  auto getNext = createCounter(10);

  writeln( "'getNext' is ", getNext );
  writeln( "'createCounter' is ", createCounter );

  writeln( "'typeof(getNext).stringof' is ", 
typeof(getNext).stringof );
  writeln( "'typeof(createCounter).string' is ", 
typeof(createCounter).stringof );

}
```

The output is

```
'next' is int delegate(int) pure nothrow @nogc @safe
'createCounter' is 557FFCC00968
'typeof(getNext).stringof' is int delegate(int dummy) pure 
nothrow @nogc @safe
'typeof(createCounter).string' is int delegate(int dummy) pure 
nothrow @nogc @safe function(int nextValue) pure nothrow @safe

 ```


**Why ```writeln``` doesn't treat the same way ```getNext``` and 
```createCounter```?**


Because   ```getNext``` is a delegate and ```createCounter``` is 
a function.


**Why this is a function and not a delegate?**

```auto createCounter = (int nextValue) => (int dummy) => 
nextValue++;```


Syntactically I dont see any difference:

```auto name = "expression returning a delegate"```

The reason is **D compiler takes the decision**.

If you make ```createCounter``` to depend on an external 
variable, it will be treated as delegate (because it has context 
information associated to the function: a closure)


```d
import std.stdio;

void main()
{
  int diff = 1;
  auto createCounter = (int nextValue) => () { scope(exit) 
nextValue+=diff; return nextValue;};
  writeln( "'typeof(createCounter).string' is ", 
typeof(createCounter).stringof );

}
```

Will output that createCounter is a delegate:

```
'typeof(createCounter).string' is int delegate() pure nothrow 
@nogc @safe delegate(int nextValue) pure nothrow @safe

```


What "breaks" my mind is that a compiler decision (treat a piece 
of code as function or delegate) is not completely transparent 
causing "side" effects on your code  (writeln doesn't work the 
same way:  it shows the delegate signature, but not the function 
signature).


But the decision of the compiler is predictable and you can argue 
different effects are not side effects:   only something you 
should pay attention to.


**This long and winding road toke me to a third and crazzy 
question**


Is there any way to force D compiler to treat this 
"createCounter" declaration as **delegate** instead of 
**function**?


```d
  auto createCounter = (int nextValue) => () => nextValue++;
```






Re: What is :-) ?

2023-11-20 Thread Paul Backus via Digitalmars-d-learn

On Monday, 20 November 2023 at 08:47:34 UTC, Antonio wrote:
- What is the way to do ```writeln``` work with ```Counter``` 
function the same way it works with ```next``` function?


`writeln()` should do it.


Re: What is :-) ?

2023-11-20 Thread Paul Backus via Digitalmars-d-learn

On Monday, 20 November 2023 at 08:47:34 UTC, Antonio wrote:
I understand the problem with UFCS (``next`` is not using UFCS 
because it is a delegate defined in the own main() function,  
and ``Counter``` without () is treated as a function call 
because it is UFCS eligible )


This is not UFCS, it's [optional parentheses][1], which is a 
separate language feature. (Reminder: UFCS only applies when the 
callee has the form `x.y`)


According to the spec, it's disabled for function pointers and 
delegates due to the potential for ambiguity.


[1]: https://dlang.org/spec/function.html#optional-parenthesis


Re: What is :-) ?

2023-11-20 Thread evilrat via Digitalmars-d-learn

On Monday, 20 November 2023 at 09:44:32 UTC, Antonio wrote:


- Why writeln doesn't treat ```next``` and ```Counter``` the 
same way?  (I think I understand why, but it shows a "low" 
level difference of something that syntactically is equivalent)


- What is the way to show Counter signature using ```writeln``` 
(if possible)?




I found no way to tell compiler that I don't want to call Counter 
and instead want to take the function itself, but closest thing 
is just to take the string representation at compile time (same 
as used in pragma msg) and pass it to writeln instead of Counter.


I guess this is one of these bif oof moments with UFCS, a 
function returning a (parameterless) function.


Note that in most cases you should never make runtime decisions 
on .stringof value as it is not standardized.



```
//pragma(msg, typeof(Counter)); // pure nothrow @safe int 
delegate() pure nothrow @nogc @safe(int nextValue)

enum f = typeof(Counter).stringof; // same string as above
writeln( "'Counter' is ", f);
```

Of course this works too
`writeln( "'Counter' is ", typeof(Counter).stringof);`




Re: What is :-) ?

2023-11-20 Thread Antonio via Digitalmars-d-learn

On Monday, 20 November 2023 at 09:11:07 UTC, evilrat wrote:

if you meant to take the function/delegate and not invoke try 
`` instead, otherwise it expects the parameters.


If you execute

```
writeln( "'Counter' is ",  );
```

It shows the Counter address:

```
'Counter' is 557F2567F940
```

Not the function signature like it does with ```next```


I propose a simple change:

```d
void main(){
  auto Counter = (int nextValue) => () => nextValue++;
  auto next = Counter(10);
  writeln( "'next' is ", next );
  writeln( "'Counter' is ", Counter );
}
```

first ```writeln``` shows the signature of next:
```
'next' is int delegate() pure nothrow @nogc @safe
```

second writeln shows the address of Counter
```
'Counter' is 55568953C910
```

- Why writeln doesn't treat ```next``` and ```Counter``` the same 
way?  (I think I understand why, but it shows a "low" level 
difference of something that syntactically is equivalent)


- What is the way to show Counter signature using ```writeln``` 
(if possible)?







```


Re: What is :-) ?

2023-11-20 Thread evilrat via Digitalmars-d-learn

On Monday, 20 November 2023 at 08:47:34 UTC, Antonio wrote:


Now, I uncomment the ```writeln( "'Counter' is ", Counter );``` 
line and compiler says


```
/home/antonio/Devel/topbrokers/whatsapp-srv/admin/x.d(12): 
Error: function `x.Counter(int nextValue)` is not callable 
using argument types `()`
/home/antonio/Devel/topbrokers/whatsapp-srv/admin/x.d(12):  
  too few arguments, expected 1, got 0

```

I understand the problem with UFCS (``next`` is not using UFCS 
because it is a delegate defined in the own main() function,  
and ``Counter``` without () is treated as a function call 
because it is UFCS eligible )



`writeln( "'Counter' is ", Counter );`

this code is actually internally looks like this

`writeln( "'Counter' is ", Counter() );`

if you meant to take the function/delegate and not invoke try 
`` instead, otherwise it expects the parameters.


- What is the way to do ```writeln``` work with ```Counter``` 
function the same way it works with ```next``` function?


Sorry, that's too confusing and I have no idea what you mean, 
maybe if you can explain what you are trying to achieve someone 
might be able to help you.


What is :-) ?

2023-11-20 Thread Antonio via Digitalmars-d-learn

If I run this code

```d
import std.stdio;

void main(){
  auto next = Counter(10);
  next().writeln;
  next().writeln;
  next().writeln;

  // What is "next" function?
  writeln( "'next' is ", next );
  // What is "Counter" function?   This fails
  // writeln( "'Counter' is ", Counter );
}

auto Counter(int nextValue) => () => nextValue++;
```

Executing this code results in:

```
10
11
12
'next' is int delegate() pure nothrow @nogc @safe
```

Now, I uncomment the ```writeln( "'Counter' is ", Counter );``` 
line and compiler says


```
/home/antonio/Devel/topbrokers/whatsapp-srv/admin/x.d(12): Error: 
function `x.Counter(int nextValue)` is not callable using 
argument types `()`
/home/antonio/Devel/topbrokers/whatsapp-srv/admin/x.d(12):
too few arguments, expected 1, got 0

```

I understand the problem with UFCS (``next`` is not using UFCS 
because it is a delegate defined in the own main() function,  and 
``Counter``` without () is treated as a function call because it 
is UFCS eligible )


- What is the way to do ```writeln``` work with ```Counter``` 
function the same way it works with ```next``` function?


Re: cannot find source code for runtime library file 'object.d'

2023-11-20 Thread thinkunix via Digitalmars-d-learn

denis via Digitalmars-d-learn wrote:

```
$ zypper install dmd
$ dmd main.d
Error: cannot find source code for runtime library file 'object.d'
    dmd might not be correctly installed. Run 'dmd -man' for 
installation instructions.

    config file: /etc/dmd.conf


I would say the package has files in the wrong locations.
Try the binary from dlang.org:

https://downloads.dlang.org/releases/2.x/2.105.3/dmd-2.105.3-0.openSUSE.x86_64.rpm

I'm not familiar with zypper but I'll bet you can install it by:
# zypper install ./dmd-2.105.3-0.openSUSE.x86_64.rpm

On a RHEL-like distro, this works:
# yum install ./pkgname.rpm

Just be sure to use your package manager tool (yum, zypper, whatever)
to install the binary so it can later be removed or updated.


More details:

I ran into something similar,'object.d' not found, when trying to
build dmd from source.  In the end I grabbed the prebuilt dmd binary
RPM from dlang.org and followed the locations where it placed files,
then everything "just works".

If you have the rpm command, you can run the following to get the file
list without installing it:

$ rpm -qlp pkgname.rpm

If you do not have the rpm command, you can use rpm2cpio to convert the
rpm into a cpio archive, then read it:

$ rpm2cpio pkgname.rpm > pkgname.cpio
$ cpio -itv < pkgname.cpio | more



$ cat /etc/dmd.conf
[Environment32]
DFLAGS=-I/usr/include/dlang/dmd -L-L/usr/lib -L--export-dynamic -fPIC

[Environment64]
DFLAGS=-I/usr/include/dlang/dmd -L-L/usr/lib64 -L--export-dynamic -fPIC



Here's what's in my /etc/dmd.conf;
Note there is no 'dlang' subdir in /usr/include, just 'dmd'.

cut here
[Environment32]
DFLAGS=-I/usr/include/dmd/phobos -I/usr/include/dmd/druntime/import 
-L-L/usr/lib -L--export-dynamic -fPIC


[Environment64]
DFLAGS=-I/usr/include/dmd/phobos -I/usr/include/dmd/druntime/import 
-L-L/usr/lib64 -L--export-dynamic -fPIC

cut here



$ ls /usr/include/dlang/dmd



/usr/include/dmd should have two directories:  druntime and phobos,
nothing else.

object.d lives here:
/usr/include/dmd/druntime/import/object.d



$ cat /etc/os-release
NAME="openSUSE Tumbleweed"
VERSION="20231006"

$ dmd --version
DMD64 D Compiler v2.105.3
```

Help?


If you decide to build from source, keep in mind you need a D
compiler to build dmd.  Either use a binary tarball from dlang.org,
or you have to bootstrap dmd 2.067.1 with a C++ compiler, then
keep upgrading dmd until you get to the version you want.  It can be
done and does work, but takes time.  Instructions are here:

https://wiki.dlang.org/Building_under_Posix

I'm guessing the person who build the package was thinking they
wanted to allow allow installing mulitple D compilers, all under
/usr/include/dlang, like so:

/usr/include/dlang/{dmd,gdc,ldc2}

and libraries would go under /usr/lib64/dlang/{dmd,gdc,ldc2}.
I made several attempts at this and they failed.  Like I said,
follow the locations of the dlang.org prebuilt rpm and it all
just works, or use a binary from dlang.org.

scot