• Re: Designing an object system for a compiler's data

    From luserdroog@21:1/5 to luserdroog on Wed Apr 27 20:59:55 2022
    On Wednesday, April 27, 2022 at 10:47:55 PM UTC-5, luserdroog wrote:

    So, for showing off and/or soliciting critique, here's the first draft of the new Lisp/PostScript-ish objects in C. I'm still debating whether to add arrays or just keep using lists for everything.


    #define PC10OBJECT_H


    By the way, this is the "McIllroy convention" so the guards go on the outside, deciding whether or not to even look at this file.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From luserdroog@21:1/5 to All on Wed Apr 27 20:47:54 2022
    I've been playing with parser combinators off and on for a few years now,
    and I have a new prototype in PostScript that seems to be working well.
    So it's time to translate it all to C, the first step of which is the fun part of
    designing an object system that's suitably Lisp-ish or PostScript-ish to represent the parsers and lists of arbitrary stuff.

    I've been criticized in previous versions for using a typedef'd pointer as
    my basic 'object' type that gets used everywhere. This time I don't do that. Instead the pointers are going to be in the middle and the basic object
    with be a "double wrapped" pointer or integer.

    So, for showing off and/or soliciting critique, here's the first draft of the new Lisp/PostScript-ish objects in C. I'm still debating whether to add
    arrays or just keep using lists for everything.


    #define PC10OBJECT_H


    typedef union object object;
    typedef object list;
    typedef object suspension;
    typedef object parser;
    typedef object boolean;
    typedef object operator;
    typedef operator predicate;
    typedef object fSuspension( object );
    typedef object fParser( object, list );
    typedef object fOperator( object, object );
    typedef boolean fPredicate( object, object );
    typedef object fBinaryOperator( object, object );

    typedef enum { INVALID, INT, LIST, SUSPENSION, PARSER, OPERATOR, SYMBOL, STRING, VOID } tag;
    union object { tag t;
    struct { tag t; int i; } Int;
    struct { tag t; struct list *ref; } List;
    struct { tag t; struct suspension *ref; } Suspension;
    struct { tag t; struct parser *ref; } Parser;
    struct { tag t; struct operator *ref; } Operator;
    struct { tag t; struct symbol *ref; } Symbol;
    struct { tag t; struct string *ref; } String;
    struct { tag t; void *ptr; } Void;
    };

    struct list {
    object a, b;
    };

    struct suspension {
    object env;
    fSuspension *f;
    };

    struct parser {
    object env;
    fParser *f;
    };

    struct operator {
    object env;
    fOperator *f;
    };

    struct symbol {
    int code;
    char *printname;
    object data;
    };

    struct string {
    char *ptr;
    int disposable;
    };

    extern boolean T_, NIL_;

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From luserdroog@21:1/5 to luserdroog on Thu May 5 11:37:05 2022
    On Wednesday, April 27, 2022 at 10:47:55 PM UTC-5, luserdroog wrote:
    I've been playing with parser combinators off and on for a few years now,
    and I have a new prototype in PostScript that seems to be working well.
    So it's time to translate it all to C, the first step of which is the fun part of
    designing an object system that's suitably Lisp-ish or PostScript-ish to represent the parsers and lists of arbitrary stuff.

    I've been criticized in previous versions for using a typedef'd pointer as
    my basic 'object' type that gets used everywhere. This time I don't do that. Instead the pointers are going to be in the middle and the basic object
    with be a "double wrapped" pointer or integer.

    So, for showing off and/or soliciting critique, here's the first draft of the new Lisp/PostScript-ish objects in C. I'm still debating whether to add arrays or just keep using lists for everything.


    #define PC10OBJECT_H


    typedef union object object;
    typedef object list;
    typedef object suspension;
    typedef object parser;
    typedef object boolean;
    typedef object operator;
    typedef operator predicate;
    typedef object fSuspension( object );
    typedef object fParser( object, list );
    typedef object fOperator( object, object );
    typedef boolean fPredicate( object, object );
    typedef object fBinaryOperator( object, object );

    typedef enum { INVALID, INT, LIST, SUSPENSION, PARSER, OPERATOR, SYMBOL, STRING, VOID } tag;
    union object { tag t;
    struct { tag t; int i; } Int;
    struct { tag t; struct list *ref; } List;
    struct { tag t; struct suspension *ref; } Suspension;
    struct { tag t; struct parser *ref; } Parser;
    struct { tag t; struct operator *ref; } Operator;
    struct { tag t; struct symbol *ref; } Symbol;
    struct { tag t; struct string *ref; } String;
    struct { tag t; void *ptr; } Void;
    };

    struct list {
    object a, b;
    };

    struct suspension {
    object env;
    fSuspension *f;
    };

    Darnitall. It's pretty. But I think it's not going to work.
    I can't mutate suspensions into other types behind
    the scene because the type is coupled into the handle.

    If the handle is just a pointer to a tagged union, then
    I can swap the unions in memory to change the
    suspension object into some other object and this
    works no matter how many times the suspension
    is referenced.

    With the tag pulled out to the front, then the tag may
    exist in multiple places in memory, one coupled to
    every reference. But I don't have an easy list of those
    to patch. Some may be in automatic memory in the
    call stack. Some could have already been virtualized
    and disappeared.

    Such a pretty design, sigh. I guess it's back to pointers.

    I'm not sure how I can implement lazy evaluation
    without mutating the memory representation behind
    the scenes.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From luserdroog@21:1/5 to luserdroog on Wed Jun 22 10:22:27 2022
    On Thursday, May 5, 2022 at 1:37:06 PM UTC-5, luserdroog wrote:
    On Wednesday, April 27, 2022 at 10:47:55 PM UTC-5, luserdroog wrote:
    I've been playing with parser combinators off and on for a few years now, and I have a new prototype in PostScript that seems to be working well.
    So it's time to translate it all to C, the first step of which is the fun part of
    designing an object system that's suitably Lisp-ish or PostScript-ish to represent the parsers and lists of arbitrary stuff.

    I've been criticized in previous versions for using a typedef'd pointer as my basic 'object' type that gets used everywhere. This time I don't do that.
    Instead the pointers are going to be in the middle and the basic object with be a "double wrapped" pointer or integer.

    [snip]

    Such a pretty design, sigh. I guess it's back to pointers.

    I'm not sure how I can implement lazy evaluation
    without mutating the memory representation behind
    the scenes.

    Back to pointers version available for review:

    https://codereview.stackexchange.com/questions/277525/5912/parser-combinators-in-c-redux

    or

    https://github.com/luser-dr00g/pcomb/archive/af8c3354f0a615087de79d3ccb409f32ef47d480.zip

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)