Created attachment 1893
single file, 99 lines tinylisp.c
I'm playing with
https://github.com/Robert-van-Engelen/tinylisp/blob/main/src/tinylisp.c
single file, 99 lines
with GCC:
```
$ make -B tinylisp
cc -c -o tinylisp.o tinylisp.c
cc tinylisp.o -o tinylisp
$ ./tinylisp
tinylisp
930>(+ 2 3)
5
```
wich dmd (importC):
```
$ dmd tinylisp.c # build fine
$ ./tinylisp
tinylisp
930>(+ 2 3)
ERR
930>^C
```
something goes wrong at runtime for such simple example.
Comment #1 by mingwu — 2023-10-09T07:24:02Z
BTW,
$ dmd --version
DMD64 D Compiler v2.105.0
Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved written by Walter Bright
And LDC works fine:
$ ldc2 -version
LDC - the LLVM D compiler (1.34.0):
based on DMD v2.104.2 and LLVM 16.0.6
built with LDC - the LLVM D compiler (1.34.0)
Default target: x86_64-unknown-linux-gnu
Host CPU: znver1
http://dlang.org - http://wiki.dlang.org/LDC
$ ./tinylisp
tinylisp
930>(+ 2 3)
5
Comment #2 by bugzilla — 2023-10-18T08:29:18Z
Unfortunately, it's not a very simple example. It's very dense, compressed code with no comments.
So far, I haven't found where the dmd version diverges from the gcc version. I'll look at it some more tomorrow.
Comment #3 by bugzilla — 2023-10-18T08:42:45Z
Hmm, it does work with -m32, implying a code gen problem.
Comment #4 by dkorpel — 2023-10-18T15:18:32Z
I tried reducing it with dustmite, but it's still pretty large:
```
int printf();
int sscanf();
char *strcpy();
int strcmp();
long strlen();
unsigned hp, sp = 1024, ATOM, PRIM, CONS = 0x7ffa, NIL;
double cell[1024], nil, tru, err, env;
double box(unsigned t, unsigned i)
{
double x;
*(long *)&x = (long)t << 48 | i;
return x;
}
unsigned ord(double x) { return *(unsigned *)&x; }
unsigned equ(double x, double y) { return *(unsigned *)&x == *(long *)&y; }
double atom(char *s)
{
unsigned i = 0;
while (i < hp && strcmp((char *)cell + i, s))
i += 1;
hp += strlen(strcpy((char *)cell + i, s)) + 1;
return box(ATOM, i);
}
double cons(double x, double y)
{
cell[--sp] = x;
cell[--sp] = y;
return box(CONS, sp);
}
double car(double p)
{
return p ? cell[ord(p) + 1] : err;
}
double cdr(double p)
{
return p ? cell[ord(p)] : err;
}
double pair(double v, double x, double e)
{
return cons(cons(v, x), e);
}
double assoc(double v, double e)
{
while (e && !equ(v, car(car(e))))
e = cdr(e);
return e ? cdr(car(e)) : err;
}
unsigned not(double x) { return x == NIL; }
double f_add(double t)
{
double n;
while (!not(t = cdr(t)))
n += car(t);
return n;
}
struct
{
char *s;
double (*f)();
} prim[] = {
"-", 0,
"+", f_add,
};
double apply(double f, double t)
{
return f ? prim[ord(f)].f(t) : f;
}
double eval(double x, double e)
{
return *(long *)&x >> 48 == ATOM ? assoc(x, e) : x ? apply(eval(car(x), e), x) : x;
}
char buf[40], see;
char* input = "(+ 4 4)";
int inputI = 0;
void look()
{
see = input[inputI++];
}
unsigned seeing(char c) { return c ? see <= c : see; }
char get()
{
char c = see;
look();
return c;
}
char scan()
{
int i = 0;
while (seeing(' '))
look();
return buf[i++] = get();
}
double parse();
double list()
{
double x;
return scan() == ')' ? nil : (x = parse(), cons(x, list()));
}
double atomic()
{
double n;
int i;
return sscanf(buf, "%lg%n", &n, &i) ? n : atom(buf);
}
double parse()
{
return *buf == '(' ? list() : atomic();
}
void print(double x)
{
// printf("%016lX\n", *(unsigned long*)&x);
if (x == ATOM)
printf("ERR");
else
printf("%.10lg", x);
}
int main()
{
int i;
for (i = 0; prim[i].s; ++i)
env = pair(atom(prim[i].s), box(PRIM, i), env);
double result = eval((scan(), parse()), env);
print(result);
}
```
This program prints 8 with gcc, but ERR with dmd on linux 64-bit.
Comment #5 by bugzilla — 2023-10-18T18:06:45Z
Ah, thanks Dennis! This is very helpful.
Comment #6 by mingwu — 2023-10-18T22:18:32Z
In the same github repo, there is a equivalent commented .c file (dmd generated binary has the same runtime error):
https://github.com/Robert-van-Engelen/tinylisphttps://github.com/Robert-van-Engelen/tinylisp/blob/main/src/tinylisp-commented.c
and the design doc:
https://github.com/Robert-van-Engelen/tinylisp/blob/main/tinylisp.pdf
gcc works fine:
$ make tinylisp-commented
cc tinylisp-commented.c -o tinylisp-commented
(env) zhou@joort:~/project/unzip/tinylisp/src$ ./tinylisp-commented
tinylisp
930>(+ 3 5)
8
$ dmd tinylisp-commented.c
tinylisp-commented.c: Error: module `tinylisp-commented` has non-identifier characters in filename, use module declaration instead
$ ln -s tinylisp-commented.c tinylisp_commented.c
$ dmd tinylisp_commented.c
$ ./tinylisp_commented
tinylisp
930>(+ 3 5)
ERR
# -m32 works confirmed:
$ dmd -m32 tinylisp_commented.c
$ ./tinylisp_commented
tinylisp
930>(+ 3 5)
8
Comment #7 by mingwu — 2023-10-18T22:45:12Z
BTW, dmd generate binary also have runtime error with this single file lisp:
https://github.com/Robert-van-Engelen/lisp/blob/main/src/lisp.c
src$ dmd lisp.c
src$ ./lisp
lisp
unbound define ERR 3 unbound symbol
8020+2000>
# dmd -m32 works fine:
src$ dmd -m32 lisp.c
$ ./lisp
lisp
null?
number?
...
defmacro
defun
6322+1929>
GCC, and LDC2 works fine.
Comment #8 by bugzilla — 2023-10-19T03:30:22Z
For this:
unsigned equ(double x, double y) {
return *(long long *)&x == *(long long *)&y;
}
The generated code is:
equ:
sub RSP,018h
movq [RSP],XMM0
mov RAX,[RSP]
cmp RAX,RCX <== ARRRGHHH!!
setz AL
movzx RAX,AL
add RSP,018h
ret
The `y` parameter is passed in XMM1, not RCX. The cast to long long has fooled the code generator.
I suspected something like this was happening, but it took a while to find it.
Comment #9 by dlang-bot — 2023-10-19T04:48:20Z
@WalterBright created dlang/dmd pull request #15707 "fix Issue 24181 - reading double parameter from RCX rather than XMM1" fixing this issue:
- fix Issue 24181 - reading double parameter from RCX rather than XMM1
https://github.com/dlang/dmd/pull/15707
Comment #10 by dlang-bot — 2023-10-19T06:29:49Z
dlang/dmd pull request #15707 "fix Issue 24181 - reading double parameter from RCX rather than XMM1" was merged into master:
- 9aacadb8604d7a7ee9c5226fe463ac4fe3115245 by Walter Bright:
fix Issue 24181 - reading double parameter from RCX rather than XMM1
https://github.com/dlang/dmd/pull/15707