tomhrr / dale

Lisp-flavoured C
BSD 3-Clause "New" or "Revised" License
1.03k stars 48 forks source link

uql not working correctly #121

Closed porky11 closed 6 years ago

porky11 commented 8 years ago

example program:

(import macros)

(using-namespace std.macros
(def x (macro intern (a)
  (let ((x \ (qq x (uql a))))
    (print x)
    (printf "\n")
    a)))
)

(x (a b c)) ;;while compiling this, `(x a b c)` should be printed

but uql works like uq here and prints (x (a b c))

porky11 commented 8 years ago

Fixing this would be important for writing macros. (I wrote a macro this way, and don't know another way to implement it) I don't know, where this bug could be. Maybe in definition of qq (and bqq), but it would make more sence, if there were multiple representations of a sexpression, and only get-varargs-list, returns the correct representation. (It seems that list-nodes containing a non-list-node as first argument is the same as a non-list-node with a next-node)

tomhrr commented 8 years ago

On Fri, Sep 30, 2016 at 04:36:02PM -0700, Fabio Krapohl wrote:

Fixing this would be important for writing macros. (I wrote a macro this way, and don't know another way to implement it)

The problem is that 'uql' is not unquoting the unwrapped list node of the node, but the list node itself, as per your example. The only difference between 'uq' and 'uql' is that 'uq' does not include the next-nodes of the unquoted node, whereas 'uql' does. I think this made some things simpler during earlier development, but it's unintuitive, and should be changed such that 'uql' unquotes the unwrapped list node, and that both forms (and the '-nc' variants) always include the next-nodes. In the interim, the following will work:

(import macros)

(using-namespace std.macros
  (def x (macro intern (a)
    (let ((a2 \ (@:@ a list-node))
          (x  \ (qq x (uql a2))))
      (print x)
      (printf "\n")
      a))))

(def main (fn extern-c int (void)
  (x (a b c))
  0))
porky11 commented 8 years ago

I don't think, this can be "fixed", I just didn't understand the structure of the DNode lists. if (uql (qq a)) would be the same as (uql (@:@ (qq a) list-node)) then (uql (@:@ (qq (a)) list-node)) would also be the same, and (uql (@:@ (qq (a) (b)) list-node) would mean something different, even if similar syntax

porky11 commented 7 years ago

(qq (uql list) rest) returns (list0 list1 …) instead of (list0 list1 … rest)

tomhrr commented 6 years ago

I think the problem shown by the above has been fixed indirectly at some point along the way:

$ cat test.dt
(import stdlib)

(using-namespace std.macros
  (def test-macro (macro intern (rest)
    (let ((rest-list \ (link-nodes-array (arg-count mc) rest)))
      (qq (uql rest-list) "test1" "test2"))))

  (def main (fn extern-c int (void)
    (test-macro printf "%s %s\n")
    0)))
$ dalec test.dt && ./a.out
test1 test2

Though the general unintuitiveness of the above is still not very appealing.