| 1 | //=============================================================================
|
|---|
| 2 | /// minimal lisp
|
|---|
| 3 | //=============================================================================
|
|---|
| 4 |
|
|---|
| 5 | #pragma once
|
|---|
| 6 |
|
|---|
| 7 | #include <stdio.h>
|
|---|
| 8 |
|
|---|
| 9 | #ifdef __cplusplus
|
|---|
| 10 | extern "C" {
|
|---|
| 11 | #endif
|
|---|
| 12 |
|
|---|
| 13 | /// Symbol-Expression type
|
|---|
| 14 | typedef int SExp;
|
|---|
| 15 |
|
|---|
| 16 | /// constant value
|
|---|
| 17 | #define cNil MAKE_SEXP(tOther, 0)
|
|---|
| 18 | #define cT MAKE_SEXP(tOther, 1)
|
|---|
| 19 | #define cEOF MAKE_SEXP(tOther, 2)
|
|---|
| 20 | #define cNL /* new line */ MAKE_SEXP(tOther, 3)
|
|---|
| 21 |
|
|---|
| 22 | /// flag
|
|---|
| 23 | /**
|
|---|
| 24 | use in ml_set_flag()
|
|---|
| 25 | */
|
|---|
| 26 | typedef enum {
|
|---|
| 27 | MLF_PRINT_FUNC_ARG,
|
|---|
| 28 | MLF_PRINT_MACRO_REPLACE,
|
|---|
| 29 |
|
|---|
| 30 | numofMLF
|
|---|
| 31 | } ML_FLAG;
|
|---|
| 32 |
|
|---|
| 33 | /// types
|
|---|
| 34 | typedef struct MLContext MLContext; ///< Context
|
|---|
| 35 | typedef SExp (*MLBuiltinFunc)(MLContext*, SExp); ///< Builtin function type
|
|---|
| 36 |
|
|---|
| 37 | /// functions
|
|---|
| 38 | MLContext* ml_new(void);
|
|---|
| 39 | void ml_delete(MLContext* ml);
|
|---|
| 40 |
|
|---|
| 41 | void ml_set_flag(MLContext* ml, ML_FLAG flag, int value);
|
|---|
| 42 |
|
|---|
| 43 | void ml_dump(MLContext* ml);
|
|---|
| 44 |
|
|---|
| 45 | SExp ml_read(MLContext* ml, FILE* fp);
|
|---|
| 46 | SExp ml_eval(MLContext* ml, SExp a);
|
|---|
| 47 | void ml_print(MLContext* ml, FILE* fp, SExp a);
|
|---|
| 48 | SExp ml_apply(MLContext* ml, SExp ca, SExp cd);
|
|---|
| 49 |
|
|---|
| 50 | SExp ml_resist_builtin(MLContext* ml, const char* word, MLBuiltinFunc cfunc, int b_macro);
|
|---|
| 51 | SExp ml_create_lambda(MLContext* ml, SExp arg_body);
|
|---|
| 52 | void ml_defmacro(MLContext* ml, SExp symb, SExp arg_body);
|
|---|
| 53 |
|
|---|
| 54 | void ml_runtime_error(MLContext* ml, SExp a, const char* msg);
|
|---|
| 55 |
|
|---|
| 56 |
|
|---|
| 57 | SExp ml_int2sexp(int x); ///< int -> sexp
|
|---|
| 58 | int ml_sexp2int(SExp a); ///< sexp -> int
|
|---|
| 59 |
|
|---|
| 60 | SExp ml_cons(MLContext* ml, SExp car, SExp cdr); ///< cons
|
|---|
| 61 | SExp ml_car(MLContext* ml, SExp a); ///< car
|
|---|
| 62 | SExp ml_cdr(MLContext* ml, SExp a); ///< cdr
|
|---|
| 63 | void ml_rplaca(MLContext* ml, SExp cs, SExp a); ///< car ���u��
|
|---|
| 64 | void ml_rplacd(MLContext* ml, SExp cs, SExp d); ///< cdr ���u��
|
|---|
| 65 |
|
|---|
| 66 | void ml_setq(MLContext* ml, SExp symb, SExp arg_body); ///< setq
|
|---|
| 67 | SExp ml_find_symbol(MLContext* ml, const char* str, const char* end, int b_make); ///< �V���{���쐬
|
|---|
| 68 |
|
|---|
| 69 | const char* ml_get_string(MLContext* ml, SExp symb); ///< string
|
|---|
| 70 |
|
|---|
| 71 |
|
|---|
| 72 |
|
|---|
| 73 | /// implementation detail
|
|---|
| 74 |
|
|---|
| 75 | /// define
|
|---|
| 76 | #define TYPE_BITS (8)
|
|---|
| 77 | #define VAL_MASK (-1 << TYPE_BITS)
|
|---|
| 78 | #define MAKE_SEXP(t, val) ((t) | ((val) << TYPE_BITS))
|
|---|
| 79 |
|
|---|
| 80 | /// type of SExp
|
|---|
| 81 | #define tCell (2) ///< cell
|
|---|
| 82 | #define tSymb (6) ///< symbol
|
|---|
| 83 | #define tOther (10) ///< other (nil, t, eof)
|
|---|
| 84 | #define tFunc (14) ///< function (lambda or macro)
|
|---|
| 85 | #define tStr (18) ///< string
|
|---|
| 86 |
|
|---|
| 87 | /// macros
|
|---|
| 88 | #define SEXP_IS_INT(a) (((a) & 1) != 0)
|
|---|
| 89 | #define SEXP_TYPE(a) ((a) & ~VAL_MASK)
|
|---|
| 90 | #define SEXP_CONSP(a) (SEXP_TYPE(a) == tCell)
|
|---|
| 91 | #define SEXP_IS_ATOM(a) (!SEXP_CONSP(a))
|
|---|
| 92 |
|
|---|
| 93 | #ifdef __cplusplus
|
|---|
| 94 | } //extern "C"
|
|---|
| 95 | #endif
|
|---|