struct Cons;
struct Atom;
-// TODO(#321): get rid of gc argument from expr macros (just assume that it's `gc` in the current scope)
#define NUMBER(G, X) atom_as_expr(create_number_atom(G, X))
#define STRING(G, S) atom_as_expr(create_string_atom(G, S, NULL))
#define SYMBOL(G, S) atom_as_expr(create_symbol_atom(G, S, NULL))
-#define NATIVE(G, F) atom_as_expr(create_native_atom(G, F))
+#define NATIVE(G, F, P) atom_as_expr(create_native_atom(G, F, P))
#define CONS(G, CAR, CDR) cons_as_expr(create_cons(G, CAR, CDR))
#define NIL(G) SYMBOL(G, "nil")
+#define CAR(O) ((O).cons->car)
+#define CDR(O) ((O).cons->cdr)
+
enum ExprType
{
EXPR_ATOM = 0,
EXPR_VOID
};
-// TODO(#285): there is no way to execute struct Expr
struct Expr
{
enum ExprType type;
void destroy_expr(struct Expr expr);
void print_expr_as_sexpr(struct Expr expr);
+int expr_as_sexpr(struct Expr expr, char *output, size_t n);
// TODO(#337): EvalResult does not belong to expr unit
struct EvalResult
struct Expr expr;
};
-typedef struct EvalResult (*NativeFunction)(Gc *gc, struct Scope *scope, struct Expr args);
+
+typedef struct EvalResult (*NativeFunction)(void *param, Gc *gc, struct Scope *scope, struct Expr args);
+
+struct Native
+{
+ NativeFunction fun;
+ void *param;
+};
enum AtomType
{
long int num; // ATOM_NUMBER
char *sym; // ATOM_SYMBOL
char *str; // ATOM_STRING
- NativeFunction fun; // ATOM_NATIVE
+ struct Native native; // ATOM_NATIVE
};
};
struct Atom *create_number_atom(Gc *gc, long int num);
struct Atom *create_string_atom(Gc *gc, const char *str, const char *str_end);
struct Atom *create_symbol_atom(Gc *gc, const char *sym, const char *sym_end);
-struct Atom *create_native_atom(Gc *gc, NativeFunction fun);
+struct Atom *create_native_atom(Gc *gc, NativeFunction fun, void *param);
void destroy_atom(struct Atom *atom);
void print_atom_as_sexpr(struct Atom *atom);