opcode/variable

37 views
Skip to first unread message

Tomas By

unread,
Mar 28, 2023, 9:44:46 AM3/28/23
to chibi-...@googlegroups.com
Hi all,

I am doing these things:

|sexp_define_foreign(ctx,env,"proc",3,proc);
|puts(sexp_string_data(sexp_write_to_string(ctx,sexp_eval_string(ctx,"proc",-1,env))));
|puts(sexp_string_data(sexp_write_to_string(ctx,script)));
|sexp_eval(ctx,script,env);

and I get

|#<opcode "proc">
|(begin (proc 1 2 3))
|ERROR: undefined variable: proc

What am I missing?

/Tomas

Alex Shinn

unread,
Mar 28, 2023, 10:01:16 AM3/28/23
to chibi-...@googlegroups.com
On Tue, Mar 28, 2023 at 10:40 PM Tomas By wrote:

Subject:

It's hard to answer with only a partial program.  The following works fine for me:

sexp proc(sexp ctx, sexp self, sexp n, sexp a, sexp b, sexp c) {
  return sexp_list3(ctx, a, b, c);
}

int main(int argc, char** argv) {
  sexp ctx, env;
  sexp_gc_var2(script, tmp);
  sexp_scheme_init();
  ctx = sexp_make_eval_context(NULL, NULL, NULL, 0, 0);
  env = sexp_load_standard_env(ctx, NULL, SEXP_SEVEN);
  sexp_load_standard_ports(ctx, NULL, stdin, stdout, stderr, 1);

  sexp_gc_preserve2(ctx, script, tmp);
  sexp_define_foreign(ctx, env, "proc", 3, proc);
  puts(sexp_string_data(sexp_write_to_string(ctx, sexp_eval_string(ctx,"proc",-1,env))));
  script = sexp_list3(ctx, SEXP_ONE, SEXP_TWO, SEXP_THREE);
  script = sexp_cons(ctx, tmp=sexp_intern(ctx, "proc", -1), script);
  script = sexp_list2(ctx, tmp=sexp_intern(ctx, "begin", -1), script);
  puts(sexp_string_data(sexp_write_to_string(ctx, script)));
  tmp = sexp_eval(ctx, script, env);
  puts(sexp_string_data(sexp_write_to_string(ctx, tmp)));

  sexp_gc_release2(ctx);
  sexp_destroy_context(ctx);
}

--
Alex

Tomas By

unread,
Mar 28, 2023, 10:19:53 AM3/28/23
to chibi-...@googlegroups.com
On Tue, 28 Mar 2023 16:00:29 +0200, Alex Shinn wrote:
> It's hard to answer with only a partial program.

Well, the file is 8K and I suspect most of it is not relevant for this
issue. (And there are more files also.)


> The following works fine for me:

Ok, thanks. One obvious difference is that I read in the script from a
file, and I do not use the sexp_list* procedures anywhere.

But I cannot see how it can make sense for the first item in the list
to be an opcode and also undefined at the same time.

Can it be some problem with the underlying C procedure (ie "proc", but
it has another name in my code) ?

/Tomas

Tomas By

unread,
Mar 28, 2023, 10:20:53 AM3/28/23
to chibi-...@googlegroups.com
On Tue, 28 Mar 2023 16:19:50 +0200, Tomas By wrote:
> Well, the file is 8K


80K

/Tomas

Tomas By

unread,
Mar 28, 2023, 10:23:25 AM3/28/23
to chibi-...@googlegroups.com
On Tue, 28 Mar 2023 16:19:50 +0200, Tomas By wrote:
> Can it be some problem with the underlying C procedure (ie "proc", but
> it has another name in my code) ?


e.g. I'm returning SEXP_VOID, maybe it should be some other value?

/Tomas

Alex Shinn

unread,
Mar 28, 2023, 11:12:03 AM3/28/23
to chibi-...@googlegroups.com
Returning void wouldn't result in the undefined variable error.
There's a bug somewhere in the 80k code not posted.

You can print the address of the proc symbol to verify if it's
the same in both cases.

Otherwise, you could start by checking the results of every
sexp_ function for errors, and gradually adding prints.

--
Alex

--
You received this message because you are subscribed to the Google Groups "chibi-scheme" group.
To unsubscribe from this group and stop receiving emails from it, send an email to chibi-scheme...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/chibi-scheme/87wn31dkf9.wl-tomas%40basun.net.

Tomas By

unread,
Mar 28, 2023, 11:23:07 AM3/28/23
to chibi-...@googlegroups.com
On Tue, 28 Mar 2023 16:19:50 +0200, Tomas By wrote:
> One obvious difference is that I read in the script from a file,

Here is what I am doing:

| o = sexp_read(ctx,port);
| tail = sexp_cdr(o);
| code = sexp_cdr(tail);

"code" is the script.


On Tue, 28 Mar 2023 17:11:48 +0200, Alex Shinn wrote:
> You can print the address of the proc symbol to verify if it's
> the same in both cases.

Not sure what you mean. I do not have the addresses in the C code?


> Otherwise, you could start by checking the results of every
> sexp_ function for errors, and gradually adding prints.

Yeah, haha, there's only a few of those. But it seems to work fine all
the way up to the eval, so there shouldn't be any exceptions along the
way?

Is there some way to print out the script verbosely, ie indicating
what Scheme thinks all the pieces are?

/Tomas

Alex Shinn

unread,
Mar 28, 2023, 11:36:34 AM3/28/23
to chibi-...@googlegroups.com
On Wed, Mar 29, 2023 at 12:23 AM Tomas By <to...@basun.net> wrote:

On Tue, 28 Mar 2023 17:11:48 +0200, Alex Shinn wrote:
> You can print the address of the proc symbol to verify if it's
> the same in both cases.

Not sure what you mean. I do not have the addresses in the C code?

You can print pointers in C like this:

  printf("%p\n", sexp);
 
Is there some way to print out the script verbosely, ie indicating
what Scheme thinks all the pieces are?

write will do this.  If unsure you can print out the object types:

  sexp_write(ctx, sexp_object_type_name(ctx, x), out)

--
Alex

Tomas By

unread,
Mar 28, 2023, 11:49:36 AM3/28/23
to chibi-...@googlegroups.com
On Tue, 28 Mar 2023 17:36:17 +0200, Alex Shinn wrote:
> You can print pointers in C

Yes, but if I do eval_string("name") and get back a string just saying
"opcode name" then I do not have the address anywhere?

Also when I do define_foreign, I only pass the name and the C proc, so
which address is it you mean?

(What is the return value of sexp_define_foreign, btw? It does not
seem to be in the manual.)

/Tomas

Alex Shinn

unread,
Mar 28, 2023, 11:56:20 AM3/28/23
to chibi-...@googlegroups.com
sexp_eval_string returns an sexp, not a string.

sexp_define_foreign returns the opcode, or an exception on failure.

--
Alex

--
You received this message because you are subscribed to the Google Groups "chibi-scheme" group.
To unsubscribe from this group and stop receiving emails from it, send an email to chibi-scheme...@googlegroups.com.

Tomas By

unread,
Mar 28, 2023, 12:03:20 PM3/28/23
to chibi-...@googlegroups.com
On Tue, 28 Mar 2023 17:36:17 +0200, Alex Shinn wrote:
So this "out" here... Googling I find this:

|out = sexp_param_ref(ctx,env,sexp_global(ctx,SEXP_G_CUR_OUT_SYMBOL));

but my compiler chokes on this. (param_ref, apparently).

Is there some simpler way to just get stdout in C?

/Tomas

Tomas By

unread,
Mar 28, 2023, 1:50:15 PM3/28/23
to chibi-...@googlegroups.com
On Tue, 28 Mar 2023 17:11:48 +0200, Alex Shinn wrote:
> There's a bug somewhere in the 80k code not posted.


I think the problem may be that the C proc returns an exception. When
I change to the whole expression with parameters in the eval_string,
then it seems to print a partial error message (ie just the message,
not the offending value).

So "sexp_eval" does not pass exceptions upwards? Do I need to traverse
myself?

Also, is there some way to get a C float from any Scheme number? It
seems unnecessary to insist on exact types when Scheme doesn't.

/Tomas

Tomas By

unread,
Mar 28, 2023, 1:59:00 PM3/28/23
to chibi-...@googlegroups.com
On Tue, 28 Mar 2023 19:50:12 +0200, Tomas By wrote:
> So "sexp_eval" does not pass exceptions upwards?

From `foreign' procedures I mean.

/Tomas

Tomas By

unread,
Mar 28, 2023, 2:02:13 PM3/28/23
to chibi-...@googlegroups.com
On Tue, 28 Mar 2023 19:50:12 +0200, Tomas By wrote:
> I think the problem may be that the C proc returns an exception.


And just to make sure: a string like "1.0" will become a Scheme
`flonum' ?

I use `sexp_flonum(s)' and it seems to fail for string like that.

/Tomas

Tomas By

unread,
Mar 28, 2023, 2:11:35 PM3/28/23
to chibi-...@googlegroups.com
On Tue, 28 Mar 2023 19:50:12 +0200, Tomas By wrote:
> I think the problem may be that the C proc returns an exception.


Well, no I still get the undefined variable at the top.

So SEXP_VOID becomes #<undef> ?

/Tomas

Tomas By

unread,
Mar 28, 2023, 2:18:06 PM3/28/23
to chibi-...@googlegroups.com
On Tue, 28 Mar 2023 20:11:32 +0200, Tomas By wrote:
> On Tue, 28 Mar 2023 19:50:12 +0200, Tomas By wrote:
> > I think the problem may be that the C proc returns an exception.
>
> Well, no I still get the undefined variable at the top.



I have these right next to each other:

|puts(sexp_string_data(sexp_write_to_string(ctx,sexp_eval_string(ctx,"(proc 0.1 0.2 0.3)",-1,env))));
|res = sexp_eval(ctx,script,env);

and get:

|#<undef>
|ERROR: undefined variable: proc

So no exception from the proc. I have not yet been able to determine
if it actually works also.

/Tomas

Tomas By

unread,
Apr 10, 2023, 11:59:15 AM4/10/23
to chibi-...@googlegroups.com
Hi all,

I now get a segmentation violation at a call to "sex_gc_preserve2".

I have a C struct that I pass around, that, among other things,
contains a Scheme context. I am not "preserving" this, and I am not
sure how that should work. Can I do

sexp_gc_preserve1(ctx,ctx)

?

(It does not seem to work, but am not sure what the errors mean. They
are on another machine so cannot copy paste.)

And is there some problem with calling sexp_gc_preserve "recursively" as in

sexp_gc_preserve2(ctx,a,b)
(call to another procedure, ctx as parameter)
sexp_gc_preserve2(ctx,c,d)
sexp_gc_release2(ctx,c,d)
(return from procedure)
sexp_gc_release2(ctx,a,b)

?

/Tomas

Tomas By

unread,
Apr 10, 2023, 12:21:42 PM4/10/23
to chibi-...@googlegroups.com
On Mon, 10 Apr 2023 17:59:12 +0200, Tomas By wrote:
> I now get a segmentation violation at a call to "sex_gc_preserve2".


Well that was a silly mistake. I had not initialised at that point.

/Tomas

Tomas By

unread,
Apr 10, 2023, 1:37:30 PM4/10/23
to chibi-...@googlegroups.com
On Mon, 10 Apr 2023 17:59:12 +0200, Tomas By wrote:
> I have a C struct that I pass around, that, among other things,
> contains a Scheme context.


Moving forward here...

How important is this bit: "Because [sexp_gc_varN] is a declaration it
must occur at the beginning of your function" ?

It seems to compile even if it is not at the beginning.

I have this situation:

void proc(...) {
(handle stuff, get pointer g)
(other things)
sexp_gc_var(...)
sexp_gc_preserve(g->ctx,...)
(stuff)
}

Even if I move it as much forward as I can, there must be other
operations before so that I can get the pointer.

Do I need to split this into two procedures?

/Tomas

Alex Shinn

unread,
Apr 10, 2023, 10:58:40 PM4/10/23
to chibi-...@googlegroups.com
On Tue, Apr 11, 2023 at 2:37 AM Tomas By <to...@basun.net> wrote:
On Mon, 10 Apr 2023 17:59:12 +0200, Tomas By wrote:
> I have a C struct that I pass around, that, among other things,
> contains a Scheme context.


Moving forward here...

How important is this bit: "Because [sexp_gc_varN] is a declaration it
must occur at the beginning of your function" ?

It seems to compile even if it is not at the beginning.

gcc allows this by default but it's not valid c89.  It would fail with -pedantic.
With -std=c99 it would work either way.
 

I have this situation:

void proc(...) {
  (handle stuff, get pointer g)
  (other things)
  sexp_gc_var(...)
  sexp_gc_preserve(g->ctx,...)
  (stuff)
}

Even if I move it as much forward as I can, there must be other
operations before so that I can get the pointer.

Do I need to split this into two procedures?

/Tomas

--
You received this message because you are subscribed to the Google Groups "chibi-scheme" group.
To unsubscribe from this group and stop receiving emails from it, send an email to chibi-scheme...@googlegroups.com.

Tomas By

unread,
Apr 11, 2023, 5:54:18 AM4/11/23
to chibi-...@googlegroups.com
On Tue, 28 Mar 2023 20:18:03 +0200, Tomas By wrote:
> I have these right next to each other:
> |puts(sexp_string_data(sexp_write_to_string(ctx,sexp_eval_string(ctx,"(proc 0.1 0.2 0.3)",-1,env))));
> |res = sexp_eval(ctx,script,env);
> and get:
> |#<undef>
> |ERROR: undefined variable: proc


Have now tried

|puts(sexp_string_data(sexp_write_to_string(ctx,sexp_env_bindings(env))));

and get

|... #<invalid type tag: 2021028896> ...

seems step in right direction, no?

How do I find out more about this? Knowing which "type" it is, for
example, would seem to be helpful.

/Tomas

Tomas By

unread,
Apr 11, 2023, 1:58:21 PM4/11/23
to chibi-...@googlegroups.com
On Tue, 28 Mar 2023 15:40:47 +0200, Tomas By wrote:
> Hi all,
> I am doing these things: [...] and I get
> |#<opcode "proc">
> |(begin (proc 1 2 3))
> |ERROR: undefined variable: proc
> What am I missing?


I think I have narrowed it down now, to this convoluted process I use
to pass a piece of data from outside Scheme to inside the script.

Essentially I do this:

| type = sexp_register_c_type(ctx,sexp_c_string(ctx,"type",-1),NULL);
| sym = sexp_intern(ctx,"some-name",-1);
| val = sexp_make_cpointer(ctx,type,(void*)data,NULL,0);
| sexp_env_define(ctx,env,sym,val);

and the idea is that "(some-name)" in the script returns the "data".

What is wrong? Any better way?

/Tomas

Tomas By

unread,
Apr 11, 2023, 2:24:38 PM4/11/23
to chibi-...@googlegroups.com
On Tue, 11 Apr 2023 19:58:17 +0200, Tomas By wrote:
> | type = sexp_register_c_type(ctx,sexp_c_string(ctx,"type",-1),NULL);


|type = (sexp_uint_t)sexp_register_c_type(ctx,sexp_c_string(ctx,"type",-1),NULL);

/Tomas

Tomas By

unread,
Apr 11, 2023, 2:54:21 PM4/11/23
to chibi-...@googlegroups.com
On Tue, 11 Apr 2023 19:58:17 +0200, Tomas By wrote:
> and the idea is that "(some-name)" in the script returns the "data".


Should be "some-name", without the brackets, and this is what produces
the "invalid type tag".

/Tomas

Tomas By

unread,
Apr 11, 2023, 3:13:17 PM4/11/23
to chibi-...@googlegroups.com
On Tue, 11 Apr 2023 20:54:17 +0200, Tomas By wrote:
> Should be "some-name", without the brackets, and this is what produces
> the "invalid type tag".


"sexp_lookup_type" seems to print the right name, whatever that might mean.

/Tomas

Alex Shinn

unread,
Apr 12, 2023, 12:20:43 AM4/12/23
to chibi-...@googlegroups.com
An invalid tag means that whatever you are looking at is not an sexp.  Either the pointer is wrong or you have memory corruption.

You can try compiling with Boehm GC.  Also compiling with -DSAFE_ACCESSORS can help catch some errors earlier.

--
Alex

--
You received this message because you are subscribed to the Google Groups "chibi-scheme" group.
To unsubscribe from this group and stop receiving emails from it, send an email to chibi-scheme...@googlegroups.com.

Tomas By

unread,
Apr 12, 2023, 3:04:17 AM4/12/23
to chibi-...@googlegroups.com
On Wed, 12 Apr 2023 06:20:27 +0200, Alex Shinn wrote:
> You can try compiling with Boehm GC. Also compiling with -DSAFE_ACCESSORS can help catch some
> errors earlier.


Neither seems to make any difference.

/Tomas

Tomas By

unread,
Apr 12, 2023, 3:36:25 AM4/12/23
to chibi-...@googlegroups.com
On Wed, 12 Apr 2023 06:20:27 +0200, Alex Shinn wrote:
> [...] memory corruption.


The manual says "sexp_context_env(sexp ctx) Returns the current
default environment associated with the context ctx."

So if I do this

1. env = sexp_context_env(ctx)
2. stuff happens to ctx
3. stuff happens to env
4. e2 = sexp_context_env(ctx)

Are env and e2 the same or could they be different?

/Tomas

Tomas By

unread,
Apr 16, 2023, 2:18:28 PM4/16/23
to chibi-...@googlegroups.com
On Wed, 12 Apr 2023 06:20:27 +0200, Alex Shinn wrote:
> An invalid tag means that whatever you are looking at is not an
> sexp. Either the pointer is wrong or you have memory corruption.


So if I have the result of sexp_register_c_type, in "p", and I do (at
a later point)

sexp_object_type_name(ctx,(sexp)p)

and it just says "Type", does that mean it's ok? Not corrupted?

/Tomas

Tomas By

unread,
Apr 16, 2023, 2:19:37 PM4/16/23
to chibi-...@googlegroups.com
On Sun, 16 Apr 2023 20:18:24 +0200, Tomas By wrote:
> So if I have the result of sexp_register_c_type, in "p", and I do (at
> a later point)
> sexp_object_type_name(ctx,(sexp)p)
> and it just says "Type", does that mean it's ok? Not corrupted?


And is there any way to get more info about the type, from just the "p"?

/Tomas

Alex Shinn

unread,
Apr 18, 2023, 9:17:20 PM4/18/23
to chibi-...@googlegroups.com
sexp_type_name(type) returns the name of the type.

sexp_object_type_name(ctx, obj) returns the name of the type of obj.

So sexp_object_type_name(ctx,(sexp)p) for the result of registering a type should always be "Type" on success.
 

/Tomas

--
You received this message because you are subscribed to the Google Groups "chibi-scheme" group.
To unsubscribe from this group and stop receiving emails from it, send an email to chibi-scheme...@googlegroups.com.

Tomas By

unread,
Apr 20, 2023, 7:19:32 AM4/20/23
to chibi-...@googlegroups.com
Hi all,

So it does not seem to be the type tag, as I got rid of the error by
using lookup_type instead.

But generally, if I have a (preserved) scheme variable in a procedure,
copies it to a global, and then exits the procedure, calling gc_release
at the end, does the GC understand there is still a live copy? Or do I
need to do something more? Or should it not be preserved in the first
place?

(I also not that this "undefined variable" error only happens at the
top level in the script. Nested calls to the same procedure does not
raise the error. Furthermore, it does not seem to be the procedure
itself, as I have tried a dozen different ones now, all with the same
result.)

/Tomas



On Tue, 28 Mar 2023 15:40:47 +0200, Tomas By wrote:
> I am doing these things:
>
> |sexp_define_foreign(ctx,env,"proc",3,proc);
> |puts(sexp_string_data(sexp_write_to_string(ctx,sexp_eval_string(ctx,"proc",-1,env))));
> |puts(sexp_string_data(sexp_write_to_string(ctx,script)));
> |sexp_eval(ctx,script,env);

Tomas By

unread,
Apr 22, 2023, 5:22:36 AM4/22/23
to chibi-...@googlegroups.com
Hi again,

I found this in an old msg:

On Nov 14, 2013, 12:16:23 AM, Alex Shinn wrote:
> Ah, looking at this and the arg list you generate the
> problem may be elsewhere. From C you need to
> guard _every_ result, so you can't just chain calls
> like this. [...]
> What you're doing is likely causing memory errors
> corrupting the whole program.


I'm just wondering how literally this is meant?

In a number of cases I ha[ve|d] things like

| sexp_equalp(ctx,smthng,sexp_intern(ctx,"somethingelse",-1))

which I have split apart, after introducing another variable, but it
has not made any difference at all that I can see.

As long as the nested proc does not raise an exception, is there even
a theoretical possibility nested calls might cause problems?

/Tomas

Tomas By

unread,
Apr 24, 2023, 5:28:51 AM4/24/23
to chibi-...@googlegroups.com
Hello everybody,

So if I just do

| sexp p;
| p = sexp_c_string(ctx,"whatever",-1);

and not change p again, then it is not necessary to use
preserve/release, as it is just a local var that does not change?

/Tomas

Alex Shinn

unread,
Apr 25, 2023, 9:48:51 AM4/25/23
to chibi-...@googlegroups.com
No, Scheme doesn't know anything about local C variables, p can get reclaimed in the next GC.

--
You received this message because you are subscribed to the Google Groups "chibi-scheme" group.
To unsubscribe from this group and stop receiving emails from it, send an email to chibi-scheme...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages