Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion doc/capi.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ fe_Context *ctx = fe_open(data, size);
fe_close(ctx);
free(data);
```

If you are building a project on a big-endian system, you must `#define FE_BIGENDIAN` before compiling.

## Running a script
To run a script it should first be read then evaluated; this should be
Expand Down
4 changes: 2 additions & 2 deletions doc/impl.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,8 @@ to keep the implementation terse, but should not hinder normal usage:
* The garbage collector recurses on the `CAR` of objects thus deeply nested
`CAR`s may overflow the C stack — an object's `CDR` is looped on and will not
overflow the stack
* The storage of an object's type and GC mark assumes a little-endian system and
will not work correctly on systems of other endianness
* The storage of an object's type and GC mark assumes a little-endian or
big-endian system and will not work correctly on systems of other endianness
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"other endianness"?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have heard that there is mixed-endian (not bi-endian), but I don't even know where it is actually used. So I'm not sure if the issue is completely solved.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, mixed-endian is rather academic
https://en.wikipedia.org/wiki/Endianness#Middle-endian

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have a new phobia: the obsessive feeling that there is a third byte order somewhere.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI I made a big endian PowerPC port http://aminet.net/package/dev/lang/fe

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From personal experience, I realized that it is very inconvenient to check every time you need #define FE_BIGENDIAN. So, I made an automatic endian check. If you consider it necessary, you can update your port.

* Proper tailcalls are not implemented — `while` can be used for iterating over
lists
* Strings are null-terminated and therefor not binary safe
14 changes: 10 additions & 4 deletions src/fe.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,20 @@
#define unused(x) ( (void) (x) )
#define car(x) ( (x)->car.o )
#define cdr(x) ( (x)->cdr.o )
#define tag(x) ( (x)->car.c )
#define isnil(x) ( (x) == &nil )
#define type(x) ( tag(x) & 0x1 ? tag(x) >> 2 : FE_TPAIR )
#define settype(x,t) ( tag(x) = (t) << 2 | 1 )
#define number(x) ( (x)->cdr.n )
#define prim(x) ( (x)->cdr.c )
#define cfunc(x) ( (x)->cdr.f )
#define strbuf(x) ( &(x)->car.c + 1 )
#define prim(x) ( *(x)->cdr.s )

#ifdef FE_BIGENDIAN
#define tag(x) ( (x)->car.s[STRBUFSIZE] )
#define strbuf(x) ( (x)->car.s )
#else
#define tag(x) ( *(x)->car.s )
#define strbuf(x) ( (x)->car.s + 1 )
#endif

#define STRBUFSIZE ( (int) sizeof(fe_Object*) - 1 )
#define GCMARKBIT ( 0x2 )
Expand All @@ -57,7 +63,7 @@ static const char *typenames[] = {
"func", "macro", "prim", "cfunc", "ptr"
};

typedef union { fe_Object *o; fe_CFunc f; fe_Number n; char c; } Value;
typedef union { fe_Object *o; fe_CFunc f; fe_Number n; char s[STRBUFSIZE + 1]; } Value;

struct fe_Object { Value car, cdr; };

Expand Down