Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Messages - Alisaxy

#1
Quote from: "ralph.ronnquist"Nice idea. I assume the 'rot in setting rotX should be 'rotX rather.


Oops, a typo! Yeah, should be "rotX" or any location to the generator in question. Could be a path to a list element like this "(list-name 0)". Yes, "generator" would be more appropriate, since tasklets are basically software thread emulations whilst generators are just yielding functions.
#2
I was trying to wrap my head around all of the power newLISP offers, figuring that the lack of coroutines or tasklets which I very much need, wouldn't be much of a problem to fix. It appears I was right and here's a slightly more advanced rotating generator factory pattern. One could easily adopt it for any type of a generator factory. Who needs "yield", right?



self-modifying version:

(setf rotating-tasklet^ (fn (loc body)
 (rotate body)
  (letex (loc loc body body)
   (expand (setf loc (fn (arg)
    (pop loc -1)
    (push (first (rotate 'body -1)) loc -1)
    'first-of-body-goes-here))))))

slightly more concise eval version:

(setf rotating-tasklet^ (fn (loc body)
 (rotate body)
  (letex (loc loc body body)
   (expand (setf loc (fn (arg)
   (eval (first (rotate 'body -1)))))))))

usage:

(rotating-tasklet^ 'rot
 '((+ 10 arg)
   (+ 11 arg)
   (+ 12 arg)))
(rotating-tasklet^ 'rotX
  '((println "first")
    (println "second")
    (println "third")))
(rotX)
(println (rot 1000))
(rotX)
(println (rot 2500))
(rotX)
(println (rot 333))

Not sure which version is better. I have a sub-conscious distrust for eval (all those years using js in my day job), but it is probably the better version. I anticipate though that the first version would be more elegant if the function would become more complex.



slightly shorter no eval version using setf instead of pop/push

(setf rotating-tasklet^ (fn (loc body)
 (rotate body)
  (letex (loc loc body body)
   (expand (setf loc (fn (arg)
    (setf (last loc) (first (rotate 'body -1)))
    'first-of-body-goes-here))))))


Just a suggestion: a way to refer to the function itself in an $it fashion would make newLISP an even more powerful language. Right now if you wish to relocate or copy such construct you would have to provide it with a precise future location, which can get unwieldy and just isn't all that elegant to be honest. With a let's call it a "$self" one could forgo such needless gymnastics.



EDIT: incorporated setf into all patterns.
#3
Hello,



I'm trying to embed newlisp into the Unreal engine through a dynamic library.

I register functions like this in my C++ code: newlispCallback("<functionNameInNewLisp>", (long)<functionName>, NULL);

I'm having no troubles with calling my C functions from newlisp with primitives and null-terminated strings. I however am having problems with collections other than newlisp strings, those being lists and arrays.



I'm also wondering if there's a proper way to call a variadic function? I tried it, but it gave me a huge arguments lists with my two values being somewhere in the middle. My C/C++ skills are a bit rusty, so the latter problem may be due to that.



So I was mostly wondering what the lists and arrays translate to in C.





Thanks!



EDIT: figured out the varargs. Most of the problem solved. :)
void print(long arg...) {
va_list ap;
va_start(ap, arg);
for (int i = arg; i >= 0; i = va_arg(ap, int))
printf("HAHA: %d ", i);
va_end(ap);
putchar('n');
}


EDIT v2: Getting this literal: -858993460 at the end of my varargs. Why is that exactly I wonder?



EDIT v3: varargs for c_strings:

#define current_va_arg(list, type) (*(type *)(list - sizeof(type)))
#define increment_va_arg(list, type) (*(type *)(list += sizeof(type)))
void printStr(int varargLen, const char * args...) {
va_list vargs;
const char* buffer;
va_start(vargs, args);
for (int i = 0; i < varargLen; i++) {
buffer = current_va_arg(vargs, const char *);
cout << buffer << endl;
increment_va_arg(vargs, const char *);
}
va_end(vargs);
}


No idea why it works for integers, but has to be hacked for c_strings.

I should always give the length of the vararg list as the first parameter. I'll change my first example.

Hehe, not even a full-time C-programmer.



EDIT v4:



The latest version of integer varargs, same macros apply.

void print(int varargLen, const long args...) {
va_list vargs;
long buffer;
va_start(vargs, args);
for (int i = 0; i < varargLen; i++) {
buffer = current_va_arg(vargs, const long);
cout << "vararg " << buffer << endl;
increment_va_arg(vargs, const long);
}
va_end(vargs);
}

Now I have an idea why the second one was behaving weirdly under a shallow inspection. I'll keep on using those two macros I made instead of the vanilla method.